* transformRangeTableSample --- transform a TABLESAMPLE clause * * Caller has already transformed rts->relation, we just have to validate * the remaining fields and create a TableSampleClause node. */
| 1120 | * the remaining fields and create a TableSampleClause node. |
| 1121 | */ |
| 1122 | static TableSampleClause * |
| 1123 | transformRangeTableSample(ParseState *pstate, RangeTableSample *rts) |
| 1124 | { |
| 1125 | TableSampleClause *tablesample; |
| 1126 | Oid handlerOid; |
| 1127 | Oid funcargtypes[1]; |
| 1128 | TsmRoutine *tsm; |
| 1129 | List *fargs; |
| 1130 | ListCell *larg, |
| 1131 | *ltyp; |
| 1132 | |
| 1133 | /* |
| 1134 | * To validate the sample method name, look up the handler function, which |
| 1135 | * has the same name, one dummy INTERNAL argument, and a result type of |
| 1136 | * tsm_handler. (Note: tablesample method names are not schema-qualified |
| 1137 | * in the SQL standard; but since they are just functions to us, we allow |
| 1138 | * schema qualification to resolve any potential ambiguity.) |
| 1139 | */ |
| 1140 | funcargtypes[0] = INTERNALOID; |
| 1141 | |
| 1142 | handlerOid = LookupFuncName(rts->method, 1, funcargtypes, true); |
| 1143 | |
| 1144 | /* we want error to complain about no-such-method, not no-such-function */ |
| 1145 | if (!OidIsValid(handlerOid)) |
| 1146 | ereport(ERROR, |
| 1147 | (errcode(ERRCODE_UNDEFINED_OBJECT), |
| 1148 | errmsg("tablesample method %s does not exist", |
| 1149 | NameListToString(rts->method)), |
| 1150 | parser_errposition(pstate, rts->location))); |
| 1151 | |
| 1152 | /* check that handler has correct return type */ |
| 1153 | if (get_func_rettype(handlerOid) != TSM_HANDLEROID) |
| 1154 | ereport(ERROR, |
| 1155 | (errcode(ERRCODE_WRONG_OBJECT_TYPE), |
| 1156 | errmsg("function %s must return type %s", |
| 1157 | NameListToString(rts->method), "tsm_handler"), |
| 1158 | parser_errposition(pstate, rts->location))); |
| 1159 | |
| 1160 | /* OK, run the handler to get TsmRoutine, for argument type info */ |
| 1161 | tsm = GetTsmRoutine(handlerOid); |
| 1162 | |
| 1163 | tablesample = makeNode(TableSampleClause); |
| 1164 | tablesample->tsmhandler = handlerOid; |
| 1165 | |
| 1166 | /* check user provided the expected number of arguments */ |
| 1167 | if (list_length(rts->args) != list_length(tsm->parameterTypes)) |
| 1168 | ereport(ERROR, |
| 1169 | (errcode(ERRCODE_INVALID_TABLESAMPLE_ARGUMENT), |
| 1170 | errmsg_plural("tablesample method %s requires %d argument, not %d", |
| 1171 | "tablesample method %s requires %d arguments, not %d", |
| 1172 | list_length(tsm->parameterTypes), |
| 1173 | NameListToString(rts->method), |
| 1174 | list_length(tsm->parameterTypes), |
| 1175 | list_length(rts->args)), |
| 1176 | parser_errposition(pstate, rts->location))); |
| 1177 | |
| 1178 | /* |
| 1179 | * Transform the arguments, typecasting them as needed. Note we must also |
no test coverage detected