func_get_detail() * * Find the named function in the system catalogs. * * Attempt to find the named function in the system catalogs with * arguments exactly as specified, so that the normal case (exact match) * is as quick as possible. * * If an exact match isn't found: * 1) check for possible interpretation as a type coercion request * 2) apply the ambiguous-function resolution rules *
| 1444 | * information to be returned into the NamedArgExpr nodes. |
| 1445 | */ |
| 1446 | FuncDetailCode |
| 1447 | func_get_detail(List *funcname, |
| 1448 | List *fargs, |
| 1449 | List *fargnames, |
| 1450 | int nargs, |
| 1451 | Oid *argtypes, |
| 1452 | bool expand_variadic, |
| 1453 | bool expand_defaults, |
| 1454 | bool include_out_arguments, |
| 1455 | Oid *funcid, /* return value */ |
| 1456 | Oid *rettype, /* return value */ |
| 1457 | bool *retset, /* return value */ |
| 1458 | int *nvargs, /* return value */ |
| 1459 | Oid *vatype, /* return value */ |
| 1460 | Oid **true_typeids, /* return value */ |
| 1461 | List **argdefaults) /* optional return value */ |
| 1462 | { |
| 1463 | FuncCandidateList raw_candidates; |
| 1464 | FuncCandidateList best_candidate; |
| 1465 | |
| 1466 | /* initialize output arguments to silence compiler warnings */ |
| 1467 | *funcid = InvalidOid; |
| 1468 | *rettype = InvalidOid; |
| 1469 | *retset = false; |
| 1470 | *nvargs = 0; |
| 1471 | *vatype = InvalidOid; |
| 1472 | *true_typeids = NULL; |
| 1473 | if (argdefaults) |
| 1474 | *argdefaults = NIL; |
| 1475 | |
| 1476 | /* Get list of possible candidates from namespace search */ |
| 1477 | raw_candidates = FuncnameGetCandidates(funcname, nargs, fargnames, |
| 1478 | expand_variadic, expand_defaults, |
| 1479 | include_out_arguments, false); |
| 1480 | |
| 1481 | /* |
| 1482 | * Quickly check if there is an exact match to the input datatypes (there |
| 1483 | * can be only one) |
| 1484 | */ |
| 1485 | for (best_candidate = raw_candidates; |
| 1486 | best_candidate != NULL; |
| 1487 | best_candidate = best_candidate->next) |
| 1488 | { |
| 1489 | /* if nargs==0, argtypes can be null; don't pass that to memcmp */ |
| 1490 | if (nargs == 0 || |
| 1491 | memcmp(argtypes, best_candidate->args, nargs * sizeof(Oid)) == 0) |
| 1492 | break; |
| 1493 | } |
| 1494 | |
| 1495 | if (best_candidate == NULL) |
| 1496 | { |
| 1497 | /* |
| 1498 | * If we didn't find an exact match, next consider the possibility |
| 1499 | * that this is really a type-coercion request: a single-argument |
| 1500 | * function call where the function name is a type name. If so, and |
| 1501 | * if the coercion path is RELABELTYPE or COERCEVIAIO, then go ahead |
| 1502 | * and treat the "function call" as a coercion. |
| 1503 | * |
no test coverage detected