* Handle functions that try to define a "DESCRIBE" callback. */
| 1252 | * Handle functions that try to define a "DESCRIBE" callback. |
| 1253 | */ |
| 1254 | static Oid |
| 1255 | validate_describe_callback(List *describeQualName, |
| 1256 | Oid returnTypeOid, |
| 1257 | ArrayType *parameterModes) |
| 1258 | { |
| 1259 | int nargs = 1; |
| 1260 | Oid inputTypeOids[1] = {INTERNALOID}; |
| 1261 | Oid *actualInputTypeOids; |
| 1262 | Oid describeReturnTypeOid; |
| 1263 | Oid describeFuncOid; |
| 1264 | bool describeReturnsSet; |
| 1265 | FuncDetailCode fdResult; |
| 1266 | AclResult aclresult; |
| 1267 | int i; |
| 1268 | |
| 1269 | if (describeQualName == NIL) |
| 1270 | return InvalidOid; |
| 1271 | |
| 1272 | /* |
| 1273 | * describe callbacks only supported for functions that return either |
| 1274 | * a pseudotype or a generic record. |
| 1275 | */ |
| 1276 | if (!TypeSupportsDescribe(returnTypeOid)) |
| 1277 | { |
| 1278 | ereport(ERROR, |
| 1279 | (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), |
| 1280 | errmsg("DESCRIBE only supported for functions returning \"record\""))); |
| 1281 | } |
| 1282 | if (parameterModes) |
| 1283 | { |
| 1284 | int len = ARR_DIMS(parameterModes)[0]; |
| 1285 | char *modes = ARR_DATA_PTR(parameterModes); |
| 1286 | |
| 1287 | Assert(ARR_NDIM(parameterModes) == 1); |
| 1288 | for (i = 0; i < len; i++) |
| 1289 | { |
| 1290 | switch (modes[i]) |
| 1291 | { |
| 1292 | case FUNC_PARAM_IN: |
| 1293 | case FUNC_PARAM_VARIADIC: |
| 1294 | break; |
| 1295 | |
| 1296 | case FUNC_PARAM_INOUT: |
| 1297 | case FUNC_PARAM_OUT: |
| 1298 | ereport(ERROR, |
| 1299 | (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), |
| 1300 | errmsg("DESCRIBE is not supported for functions " |
| 1301 | "with OUT parameters"))); |
| 1302 | break; |
| 1303 | |
| 1304 | case FUNC_PARAM_TABLE: |
| 1305 | ereport(ERROR, |
| 1306 | (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), |
| 1307 | errmsg("DESCRIBE is not supported for functions " |
| 1308 | "that return TABLE"))); |
| 1309 | break; |
| 1310 | |
| 1311 | /* above list should be exhaustive */ |
no test coverage detected