PostgreSQL Source Code git master
parse_func.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "lib/stringinfo.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "parser/parse_agg.h"
#include "parser/parse_clause.h"
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "parser/parse_relation.h"
#include "parser/parse_target.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
Include dependency graph for parse_func.c:

Go to the source code of this file.

Enumerations

enum  FuncLookupError { FUNCLOOKUP_NOSUCHFUNC , FUNCLOOKUP_AMBIGUOUS }
 

Functions

static void unify_hypothetical_args (ParseState *pstate, List *fargs, int numAggregatedArgs, Oid *actual_arg_types, Oid *declared_arg_types)
 
static Oid FuncNameAsType (List *funcname)
 
static NodeParseComplexProjection (ParseState *pstate, const char *funcname, Node *first_arg, int location)
 
static Oid LookupFuncNameInternal (ObjectType objtype, List *funcname, int nargs, const Oid *argtypes, bool include_out_arguments, bool missing_ok, FuncLookupError *lookupError)
 
NodeParseFuncOrColumn (ParseState *pstate, List *funcname, List *fargs, Node *last_srf, FuncCall *fn, bool proc_call, int location)
 
int func_match_argtypes (int nargs, Oid *input_typeids, FuncCandidateList raw_candidates, FuncCandidateList *candidates)
 
FuncCandidateList func_select_candidate (int nargs, Oid *input_typeids, FuncCandidateList candidates)
 
FuncDetailCode func_get_detail (List *funcname, List *fargs, List *fargnames, int nargs, Oid *argtypes, bool expand_variadic, bool expand_defaults, bool include_out_arguments, Oid *funcid, Oid *rettype, bool *retset, int *nvargs, Oid *vatype, Oid **true_typeids, List **argdefaults)
 
void make_fn_arguments (ParseState *pstate, List *fargs, Oid *actual_arg_types, Oid *declared_arg_types)
 
const char * funcname_signature_string (const char *funcname, int nargs, List *argnames, const Oid *argtypes)
 
const char * func_signature_string (List *funcname, int nargs, List *argnames, const Oid *argtypes)
 
Oid LookupFuncName (List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
 
Oid LookupFuncWithArgs (ObjectType objtype, ObjectWithArgs *func, bool missing_ok)
 
void check_srf_call_placement (ParseState *pstate, Node *last_srf, int location)
 

Enumeration Type Documentation

◆ FuncLookupError

Enumerator
FUNCLOOKUP_NOSUCHFUNC 
FUNCLOOKUP_AMBIGUOUS 

Definition at line 39 of file parse_func.c.

40{
FuncLookupError
Definition: parse_func.c:40
@ FUNCLOOKUP_NOSUCHFUNC
Definition: parse_func.c:41
@ FUNCLOOKUP_AMBIGUOUS
Definition: parse_func.c:42

Function Documentation

◆ check_srf_call_placement()

void check_srf_call_placement ( ParseState pstate,
Node last_srf,
int  location 
)

Definition at line 2511 of file parse_func.c.

2512{
2513 const char *err;
2514 bool errkind;
2515
2516 /*
2517 * Check to see if the set-returning function is in an invalid place
2518 * within the query. Basically, we don't allow SRFs anywhere except in
2519 * the targetlist (which includes GROUP BY/ORDER BY expressions), VALUES,
2520 * and functions in FROM.
2521 *
2522 * For brevity we support two schemes for reporting an error here: set
2523 * "err" to a custom message, or set "errkind" true if the error context
2524 * is sufficiently identified by what ParseExprKindName will return, *and*
2525 * what it will return is just a SQL keyword. (Otherwise, use a custom
2526 * message to avoid creating translation problems.)
2527 */
2528 err = NULL;
2529 errkind = false;
2530 switch (pstate->p_expr_kind)
2531 {
2532 case EXPR_KIND_NONE:
2533 Assert(false); /* can't happen */
2534 break;
2535 case EXPR_KIND_OTHER:
2536 /* Accept SRF here; caller must throw error if wanted */
2537 break;
2538 case EXPR_KIND_JOIN_ON:
2540 err = _("set-returning functions are not allowed in JOIN conditions");
2541 break;
2543 /* can't get here, but just in case, throw an error */
2544 errkind = true;
2545 break;
2547 /* okay, but we don't allow nested SRFs here */
2548 /* errmsg is chosen to match transformRangeFunction() */
2549 /* errposition should point to the inner SRF */
2550 if (pstate->p_last_srf != last_srf)
2551 ereport(ERROR,
2552 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2553 errmsg("set-returning functions must appear at top level of FROM"),
2554 parser_errposition(pstate,
2555 exprLocation(pstate->p_last_srf))));
2556 break;
2557 case EXPR_KIND_WHERE:
2558 errkind = true;
2559 break;
2560 case EXPR_KIND_POLICY:
2561 err = _("set-returning functions are not allowed in policy expressions");
2562 break;
2563 case EXPR_KIND_HAVING:
2564 errkind = true;
2565 break;
2566 case EXPR_KIND_FILTER:
2567 errkind = true;
2568 break;
2571 /* okay, these are effectively GROUP BY/ORDER BY */
2572 pstate->p_hasTargetSRFs = true;
2573 break;
2577 err = _("set-returning functions are not allowed in window definitions");
2578 break;
2581 /* okay */
2582 pstate->p_hasTargetSRFs = true;
2583 break;
2586 /* disallowed because it would be ambiguous what to do */
2587 errkind = true;
2588 break;
2589 case EXPR_KIND_GROUP_BY:
2590 case EXPR_KIND_ORDER_BY:
2591 /* okay */
2592 pstate->p_hasTargetSRFs = true;
2593 break;
2595 /* okay */
2596 pstate->p_hasTargetSRFs = true;
2597 break;
2598 case EXPR_KIND_LIMIT:
2599 case EXPR_KIND_OFFSET:
2600 errkind = true;
2601 break;
2604 errkind = true;
2605 break;
2606 case EXPR_KIND_VALUES:
2607 /* SRFs are presently not supported by nodeValuesscan.c */
2608 errkind = true;
2609 break;
2611 /* okay, since we process this like a SELECT tlist */
2612 pstate->p_hasTargetSRFs = true;
2613 break;
2615 err = _("set-returning functions are not allowed in MERGE WHEN conditions");
2616 break;
2619 err = _("set-returning functions are not allowed in check constraints");
2620 break;
2623 err = _("set-returning functions are not allowed in DEFAULT expressions");
2624 break;
2626 err = _("set-returning functions are not allowed in index expressions");
2627 break;
2629 err = _("set-returning functions are not allowed in index predicates");
2630 break;
2632 err = _("set-returning functions are not allowed in statistics expressions");
2633 break;
2635 err = _("set-returning functions are not allowed in transform expressions");
2636 break;
2638 err = _("set-returning functions are not allowed in EXECUTE parameters");
2639 break;
2641 err = _("set-returning functions are not allowed in trigger WHEN conditions");
2642 break;
2644 err = _("set-returning functions are not allowed in partition bound");
2645 break;
2647 err = _("set-returning functions are not allowed in partition key expressions");
2648 break;
2650 err = _("set-returning functions are not allowed in CALL arguments");
2651 break;
2653 err = _("set-returning functions are not allowed in COPY FROM WHERE conditions");
2654 break;
2656 err = _("set-returning functions are not allowed in column generation expressions");
2657 break;
2659 errkind = true;
2660 break;
2661
2662 /*
2663 * There is intentionally no default: case here, so that the
2664 * compiler will warn if we add a new ParseExprKind without
2665 * extending this switch. If we do see an unrecognized value at
2666 * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
2667 * which is sane anyway.
2668 */
2669 }
2670 if (err)
2671 ereport(ERROR,
2672 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2673 errmsg_internal("%s", err),
2674 parser_errposition(pstate, location)));
2675 if (errkind)
2676 ereport(ERROR,
2677 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2678 /* translator: %s is name of a SQL construct, eg GROUP BY */
2679 errmsg("set-returning functions are not allowed in %s",
2681 parser_errposition(pstate, location)));
2682}
#define Assert(condition)
Definition: c.h:815
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define _(x)
Definition: elog.c:90
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void err(int eval, const char *fmt,...)
Definition: err.c:43
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1388
const char * ParseExprKindName(ParseExprKind exprKind)
Definition: parse_expr.c:3121
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:106
@ EXPR_KIND_EXECUTE_PARAMETER
Definition: parse_node.h:76
@ EXPR_KIND_DOMAIN_CHECK
Definition: parse_node.h:69
@ EXPR_KIND_COPY_WHERE
Definition: parse_node.h:82
@ EXPR_KIND_COLUMN_DEFAULT
Definition: parse_node.h:70
@ EXPR_KIND_DISTINCT_ON
Definition: parse_node.h:61
@ EXPR_KIND_MERGE_WHEN
Definition: parse_node.h:58
@ EXPR_KIND_STATS_EXPRESSION
Definition: parse_node.h:74
@ EXPR_KIND_INDEX_EXPRESSION
Definition: parse_node.h:72
@ EXPR_KIND_MERGE_RETURNING
Definition: parse_node.h:65
@ EXPR_KIND_PARTITION_BOUND
Definition: parse_node.h:79
@ EXPR_KIND_FUNCTION_DEFAULT
Definition: parse_node.h:71
@ EXPR_KIND_WINDOW_FRAME_RANGE
Definition: parse_node.h:51
@ EXPR_KIND_VALUES
Definition: parse_node.h:66
@ EXPR_KIND_FROM_SUBSELECT
Definition: parse_node.h:44
@ EXPR_KIND_POLICY
Definition: parse_node.h:78
@ EXPR_KIND_WINDOW_FRAME_GROUPS
Definition: parse_node.h:53
@ EXPR_KIND_PARTITION_EXPRESSION
Definition: parse_node.h:80
@ EXPR_KIND_JOIN_USING
Definition: parse_node.h:43
@ EXPR_KIND_INDEX_PREDICATE
Definition: parse_node.h:73
@ EXPR_KIND_ORDER_BY
Definition: parse_node.h:60
@ EXPR_KIND_OFFSET
Definition: parse_node.h:63
@ EXPR_KIND_JOIN_ON
Definition: parse_node.h:42
@ EXPR_KIND_HAVING
Definition: parse_node.h:47
@ EXPR_KIND_INSERT_TARGET
Definition: parse_node.h:55
@ EXPR_KIND_ALTER_COL_TRANSFORM
Definition: parse_node.h:75
@ EXPR_KIND_LIMIT
Definition: parse_node.h:62
@ EXPR_KIND_WHERE
Definition: parse_node.h:46
@ EXPR_KIND_UPDATE_TARGET
Definition: parse_node.h:57
@ EXPR_KIND_SELECT_TARGET
Definition: parse_node.h:54
@ EXPR_KIND_RETURNING
Definition: parse_node.h:64
@ EXPR_KIND_GENERATED_COLUMN
Definition: parse_node.h:83
@ EXPR_KIND_NONE
Definition: parse_node.h:40
@ EXPR_KIND_CALL_ARGUMENT
Definition: parse_node.h:81
@ EXPR_KIND_GROUP_BY
Definition: parse_node.h:59
@ EXPR_KIND_OTHER
Definition: parse_node.h:41
@ EXPR_KIND_FROM_FUNCTION
Definition: parse_node.h:45
@ EXPR_KIND_TRIGGER_WHEN
Definition: parse_node.h:77
@ EXPR_KIND_FILTER
Definition: parse_node.h:48
@ EXPR_KIND_UPDATE_SOURCE
Definition: parse_node.h:56
@ EXPR_KIND_CHECK_CONSTRAINT
Definition: parse_node.h:68
@ EXPR_KIND_WINDOW_PARTITION
Definition: parse_node.h:49
@ EXPR_KIND_CYCLE_MARK
Definition: parse_node.h:84
@ EXPR_KIND_WINDOW_FRAME_ROWS
Definition: parse_node.h:52
@ EXPR_KIND_WINDOW_ORDER
Definition: parse_node.h:50
@ EXPR_KIND_VALUES_SINGLE
Definition: parse_node.h:67
bool p_hasTargetSRFs
Definition: parse_node.h:244
ParseExprKind p_expr_kind
Definition: parse_node.h:230
Node * p_last_srf
Definition: parse_node.h:248

References _, Assert, ereport, err(), errcode(), errmsg(), errmsg_internal(), ERROR, EXPR_KIND_ALTER_COL_TRANSFORM, EXPR_KIND_CALL_ARGUMENT, EXPR_KIND_CHECK_CONSTRAINT, EXPR_KIND_COLUMN_DEFAULT, EXPR_KIND_COPY_WHERE, EXPR_KIND_CYCLE_MARK, EXPR_KIND_DISTINCT_ON, EXPR_KIND_DOMAIN_CHECK, EXPR_KIND_EXECUTE_PARAMETER, EXPR_KIND_FILTER, EXPR_KIND_FROM_FUNCTION, EXPR_KIND_FROM_SUBSELECT, EXPR_KIND_FUNCTION_DEFAULT, EXPR_KIND_GENERATED_COLUMN, EXPR_KIND_GROUP_BY, EXPR_KIND_HAVING, EXPR_KIND_INDEX_EXPRESSION, EXPR_KIND_INDEX_PREDICATE, EXPR_KIND_INSERT_TARGET, EXPR_KIND_JOIN_ON, EXPR_KIND_JOIN_USING, EXPR_KIND_LIMIT, EXPR_KIND_MERGE_RETURNING, EXPR_KIND_MERGE_WHEN, EXPR_KIND_NONE, EXPR_KIND_OFFSET, EXPR_KIND_ORDER_BY, EXPR_KIND_OTHER, EXPR_KIND_PARTITION_BOUND, EXPR_KIND_PARTITION_EXPRESSION, EXPR_KIND_POLICY, EXPR_KIND_RETURNING, EXPR_KIND_SELECT_TARGET, EXPR_KIND_STATS_EXPRESSION, EXPR_KIND_TRIGGER_WHEN, EXPR_KIND_UPDATE_SOURCE, EXPR_KIND_UPDATE_TARGET, EXPR_KIND_VALUES, EXPR_KIND_VALUES_SINGLE, EXPR_KIND_WHERE, EXPR_KIND_WINDOW_FRAME_GROUPS, EXPR_KIND_WINDOW_FRAME_RANGE, EXPR_KIND_WINDOW_FRAME_ROWS, EXPR_KIND_WINDOW_ORDER, EXPR_KIND_WINDOW_PARTITION, exprLocation(), ParseState::p_expr_kind, ParseState::p_hasTargetSRFs, ParseState::p_last_srf, ParseExprKindName(), and parser_errposition().

Referenced by make_op(), and ParseFuncOrColumn().

◆ func_get_detail()

FuncDetailCode func_get_detail ( List funcname,
List fargs,
List fargnames,
int  nargs,
Oid argtypes,
bool  expand_variadic,
bool  expand_defaults,
bool  include_out_arguments,
Oid funcid,
Oid rettype,
bool *  retset,
int *  nvargs,
Oid vatype,
Oid **  true_typeids,
List **  argdefaults 
)

Definition at line 1395 of file parse_func.c.

1410{
1411 FuncCandidateList raw_candidates;
1412 FuncCandidateList best_candidate;
1413
1414 /* initialize output arguments to silence compiler warnings */
1415 *funcid = InvalidOid;
1416 *rettype = InvalidOid;
1417 *retset = false;
1418 *nvargs = 0;
1419 *vatype = InvalidOid;
1420 *true_typeids = NULL;
1421 if (argdefaults)
1422 *argdefaults = NIL;
1423
1424 /* Get list of possible candidates from namespace search */
1425 raw_candidates = FuncnameGetCandidates(funcname, nargs, fargnames,
1426 expand_variadic, expand_defaults,
1427 include_out_arguments, false);
1428
1429 /*
1430 * Quickly check if there is an exact match to the input datatypes (there
1431 * can be only one)
1432 */
1433 for (best_candidate = raw_candidates;
1434 best_candidate != NULL;
1435 best_candidate = best_candidate->next)
1436 {
1437 /* if nargs==0, argtypes can be null; don't pass that to memcmp */
1438 if (nargs == 0 ||
1439 memcmp(argtypes, best_candidate->args, nargs * sizeof(Oid)) == 0)
1440 break;
1441 }
1442
1443 if (best_candidate == NULL)
1444 {
1445 /*
1446 * If we didn't find an exact match, next consider the possibility
1447 * that this is really a type-coercion request: a single-argument
1448 * function call where the function name is a type name. If so, and
1449 * if the coercion path is RELABELTYPE or COERCEVIAIO, then go ahead
1450 * and treat the "function call" as a coercion.
1451 *
1452 * This interpretation needs to be given higher priority than
1453 * interpretations involving a type coercion followed by a function
1454 * call, otherwise we can produce surprising results. For example, we
1455 * want "text(varchar)" to be interpreted as a simple coercion, not as
1456 * "text(name(varchar))" which the code below this point is entirely
1457 * capable of selecting.
1458 *
1459 * We also treat a coercion of a previously-unknown-type literal
1460 * constant to a specific type this way.
1461 *
1462 * The reason we reject COERCION_PATH_FUNC here is that we expect the
1463 * cast implementation function to be named after the target type.
1464 * Thus the function will be found by normal lookup if appropriate.
1465 *
1466 * The reason we reject COERCION_PATH_ARRAYCOERCE is mainly that you
1467 * can't write "foo[] (something)" as a function call. In theory
1468 * someone might want to invoke it as "_foo (something)" but we have
1469 * never supported that historically, so we can insist that people
1470 * write it as a normal cast instead.
1471 *
1472 * We also reject the specific case of COERCEVIAIO for a composite
1473 * source type and a string-category target type. This is a case that
1474 * find_coercion_pathway() allows by default, but experience has shown
1475 * that it's too commonly invoked by mistake. So, again, insist that
1476 * people use cast syntax if they want to do that.
1477 *
1478 * NB: it's important that this code does not exceed what coerce_type
1479 * can do, because the caller will try to apply coerce_type if we
1480 * return FUNCDETAIL_COERCION. If we return that result for something
1481 * coerce_type can't handle, we'll cause infinite recursion between
1482 * this module and coerce_type!
1483 */
1484 if (nargs == 1 && fargs != NIL && fargnames == NIL)
1485 {
1486 Oid targetType = FuncNameAsType(funcname);
1487
1488 if (OidIsValid(targetType))
1489 {
1490 Oid sourceType = argtypes[0];
1491 Node *arg1 = linitial(fargs);
1492 bool iscoercion;
1493
1494 if (sourceType == UNKNOWNOID && IsA(arg1, Const))
1495 {
1496 /* always treat typename('literal') as coercion */
1497 iscoercion = true;
1498 }
1499 else
1500 {
1501 CoercionPathType cpathtype;
1502 Oid cfuncid;
1503
1504 cpathtype = find_coercion_pathway(targetType, sourceType,
1506 &cfuncid);
1507 switch (cpathtype)
1508 {
1510 iscoercion = true;
1511 break;
1513 if ((sourceType == RECORDOID ||
1514 ISCOMPLEX(sourceType)) &&
1515 TypeCategory(targetType) == TYPCATEGORY_STRING)
1516 iscoercion = false;
1517 else
1518 iscoercion = true;
1519 break;
1520 default:
1521 iscoercion = false;
1522 break;
1523 }
1524 }
1525
1526 if (iscoercion)
1527 {
1528 /* Treat it as a type coercion */
1529 *funcid = InvalidOid;
1530 *rettype = targetType;
1531 *retset = false;
1532 *nvargs = 0;
1533 *vatype = InvalidOid;
1534 *true_typeids = argtypes;
1535 return FUNCDETAIL_COERCION;
1536 }
1537 }
1538 }
1539
1540 /*
1541 * didn't find an exact match, so now try to match up candidates...
1542 */
1543 if (raw_candidates != NULL)
1544 {
1545 FuncCandidateList current_candidates;
1546 int ncandidates;
1547
1548 ncandidates = func_match_argtypes(nargs,
1549 argtypes,
1550 raw_candidates,
1551 &current_candidates);
1552
1553 /* one match only? then run with it... */
1554 if (ncandidates == 1)
1555 best_candidate = current_candidates;
1556
1557 /*
1558 * multiple candidates? then better decide or throw an error...
1559 */
1560 else if (ncandidates > 1)
1561 {
1562 best_candidate = func_select_candidate(nargs,
1563 argtypes,
1564 current_candidates);
1565
1566 /*
1567 * If we were able to choose a best candidate, we're done.
1568 * Otherwise, ambiguous function call.
1569 */
1570 if (!best_candidate)
1571 return FUNCDETAIL_MULTIPLE;
1572 }
1573 }
1574 }
1575
1576 if (best_candidate)
1577 {
1578 HeapTuple ftup;
1579 Form_pg_proc pform;
1580 FuncDetailCode result;
1581
1582 /*
1583 * If processing named args or expanding variadics or defaults, the
1584 * "best candidate" might represent multiple equivalently good
1585 * functions; treat this case as ambiguous.
1586 */
1587 if (!OidIsValid(best_candidate->oid))
1588 return FUNCDETAIL_MULTIPLE;
1589
1590 /*
1591 * We disallow VARIADIC with named arguments unless the last argument
1592 * (the one with VARIADIC attached) actually matched the variadic
1593 * parameter. This is mere pedantry, really, but some folks insisted.
1594 */
1595 if (fargnames != NIL && !expand_variadic && nargs > 0 &&
1596 best_candidate->argnumbers[nargs - 1] != nargs - 1)
1597 return FUNCDETAIL_NOTFOUND;
1598
1599 *funcid = best_candidate->oid;
1600 *nvargs = best_candidate->nvargs;
1601 *true_typeids = best_candidate->args;
1602
1603 /*
1604 * If processing named args, return actual argument positions into
1605 * NamedArgExpr nodes in the fargs list. This is a bit ugly but not
1606 * worth the extra notation needed to do it differently.
1607 */
1608 if (best_candidate->argnumbers != NULL)
1609 {
1610 int i = 0;
1611 ListCell *lc;
1612
1613 foreach(lc, fargs)
1614 {
1615 NamedArgExpr *na = (NamedArgExpr *) lfirst(lc);
1616
1617 if (IsA(na, NamedArgExpr))
1618 na->argnumber = best_candidate->argnumbers[i];
1619 i++;
1620 }
1621 }
1622
1623 ftup = SearchSysCache1(PROCOID,
1624 ObjectIdGetDatum(best_candidate->oid));
1625 if (!HeapTupleIsValid(ftup)) /* should not happen */
1626 elog(ERROR, "cache lookup failed for function %u",
1627 best_candidate->oid);
1628 pform = (Form_pg_proc) GETSTRUCT(ftup);
1629 *rettype = pform->prorettype;
1630 *retset = pform->proretset;
1631 *vatype = pform->provariadic;
1632 /* fetch default args if caller wants 'em */
1633 if (argdefaults && best_candidate->ndargs > 0)
1634 {
1635 Datum proargdefaults;
1636 char *str;
1637 List *defaults;
1638
1639 /* shouldn't happen, FuncnameGetCandidates messed up */
1640 if (best_candidate->ndargs > pform->pronargdefaults)
1641 elog(ERROR, "not enough default arguments");
1642
1643 proargdefaults = SysCacheGetAttrNotNull(PROCOID, ftup,
1644 Anum_pg_proc_proargdefaults);
1645 str = TextDatumGetCString(proargdefaults);
1646 defaults = castNode(List, stringToNode(str));
1647 pfree(str);
1648
1649 /* Delete any unused defaults from the returned list */
1650 if (best_candidate->argnumbers != NULL)
1651 {
1652 /*
1653 * This is a bit tricky in named notation, since the supplied
1654 * arguments could replace any subset of the defaults. We
1655 * work by making a bitmapset of the argnumbers of defaulted
1656 * arguments, then scanning the defaults list and selecting
1657 * the needed items. (This assumes that defaulted arguments
1658 * should be supplied in their positional order.)
1659 */
1660 Bitmapset *defargnumbers;
1661 int *firstdefarg;
1662 List *newdefaults;
1663 ListCell *lc;
1664 int i;
1665
1666 defargnumbers = NULL;
1667 firstdefarg = &best_candidate->argnumbers[best_candidate->nargs - best_candidate->ndargs];
1668 for (i = 0; i < best_candidate->ndargs; i++)
1669 defargnumbers = bms_add_member(defargnumbers,
1670 firstdefarg[i]);
1671 newdefaults = NIL;
1672 i = best_candidate->nominalnargs - pform->pronargdefaults;
1673 foreach(lc, defaults)
1674 {
1675 if (bms_is_member(i, defargnumbers))
1676 newdefaults = lappend(newdefaults, lfirst(lc));
1677 i++;
1678 }
1679 Assert(list_length(newdefaults) == best_candidate->ndargs);
1680 bms_free(defargnumbers);
1681 *argdefaults = newdefaults;
1682 }
1683 else
1684 {
1685 /*
1686 * Defaults for positional notation are lots easier; just
1687 * remove any unwanted ones from the front.
1688 */
1689 int ndelete;
1690
1691 ndelete = list_length(defaults) - best_candidate->ndargs;
1692 if (ndelete > 0)
1693 defaults = list_delete_first_n(defaults, ndelete);
1694 *argdefaults = defaults;
1695 }
1696 }
1697
1698 switch (pform->prokind)
1699 {
1700 case PROKIND_AGGREGATE:
1701 result = FUNCDETAIL_AGGREGATE;
1702 break;
1703 case PROKIND_FUNCTION:
1704 result = FUNCDETAIL_NORMAL;
1705 break;
1706 case PROKIND_PROCEDURE:
1707 result = FUNCDETAIL_PROCEDURE;
1708 break;
1709 case PROKIND_WINDOW:
1710 result = FUNCDETAIL_WINDOWFUNC;
1711 break;
1712 default:
1713 elog(ERROR, "unrecognized prokind: %c", pform->prokind);
1714 result = FUNCDETAIL_NORMAL; /* keep compiler quiet */
1715 break;
1716 }
1717
1718 ReleaseSysCache(ftup);
1719 return result;
1720 }
1721
1722 return FUNCDETAIL_NOTFOUND;
1723}
void bms_free(Bitmapset *a)
Definition: bitmapset.c:239
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:510
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:815
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define OidIsValid(objectId)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:225
const char * str
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
#define funcname
Definition: indent_codes.h:69
int i
Definition: isn.c:72
List * lappend(List *list, void *datum)
Definition: list.c:339
List * list_delete_first_n(List *list, int n)
Definition: list.c:983
void pfree(void *pointer)
Definition: mcxt.c:1521
FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, bool include_out_arguments, bool missing_ok)
Definition: namespace.c:1192
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
TYPCATEGORY TypeCategory(Oid type)
CoercionPathType find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, CoercionContext ccontext, Oid *funcid)
CoercionPathType
Definition: parse_coerce.h:25
@ COERCION_PATH_COERCEVIAIO
Definition: parse_coerce.h:30
@ COERCION_PATH_RELABELTYPE
Definition: parse_coerce.h:28
FuncCandidateList func_select_candidate(int nargs, Oid *input_typeids, FuncCandidateList candidates)
Definition: parse_func.c:1008
static Oid FuncNameAsType(List *funcname)
Definition: parse_func.c:1881
int func_match_argtypes(int nargs, Oid *input_typeids, FuncCandidateList raw_candidates, FuncCandidateList *candidates)
Definition: parse_func.c:923
FuncDetailCode
Definition: parse_func.h:23
@ FUNCDETAIL_MULTIPLE
Definition: parse_func.h:25
@ FUNCDETAIL_NORMAL
Definition: parse_func.h:26
@ FUNCDETAIL_PROCEDURE
Definition: parse_func.h:27
@ FUNCDETAIL_WINDOWFUNC
Definition: parse_func.h:29
@ FUNCDETAIL_NOTFOUND
Definition: parse_func.h:24
@ FUNCDETAIL_COERCION
Definition: parse_func.h:30
@ FUNCDETAIL_AGGREGATE
Definition: parse_func.h:28
#define ISCOMPLEX(typeid)
Definition: parse_type.h:59
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define linitial(l)
Definition: pg_list.h:178
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
uintptr_t Datum
Definition: postgres.h:69
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
@ COERCION_EXPLICIT
Definition: primnodes.h:734
void * stringToNode(const char *str)
Definition: read.c:90
Definition: pg_list.h:54
Definition: nodes.h:129
struct _FuncCandidateList * next
Definition: namespace.h:31
Oid args[FLEXIBLE_ARRAY_MEMBER]
Definition: namespace.h:39
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:631

References NamedArgExpr::argnumber, _FuncCandidateList::argnumbers, _FuncCandidateList::args, Assert, bms_add_member(), bms_free(), bms_is_member(), castNode, COERCION_EXPLICIT, COERCION_PATH_COERCEVIAIO, COERCION_PATH_RELABELTYPE, elog, ERROR, find_coercion_pathway(), func_match_argtypes(), func_select_candidate(), FUNCDETAIL_AGGREGATE, FUNCDETAIL_COERCION, FUNCDETAIL_MULTIPLE, FUNCDETAIL_NORMAL, FUNCDETAIL_NOTFOUND, FUNCDETAIL_PROCEDURE, FUNCDETAIL_WINDOWFUNC, funcname, FuncNameAsType(), FuncnameGetCandidates(), GETSTRUCT(), HeapTupleIsValid, i, InvalidOid, IsA, ISCOMPLEX, lappend(), lfirst, linitial, list_delete_first_n(), list_length(), _FuncCandidateList::nargs, _FuncCandidateList::ndargs, _FuncCandidateList::next, NIL, _FuncCandidateList::nominalnargs, _FuncCandidateList::nvargs, ObjectIdGetDatum(), _FuncCandidateList::oid, OidIsValid, pfree(), ReleaseSysCache(), SearchSysCache1(), str, stringToNode(), SysCacheGetAttrNotNull(), TextDatumGetCString, and TypeCategory().

Referenced by generate_function_name(), lookup_agg_function(), and ParseFuncOrColumn().

◆ func_match_argtypes()

int func_match_argtypes ( int  nargs,
Oid input_typeids,
FuncCandidateList  raw_candidates,
FuncCandidateList candidates 
)

Definition at line 923 of file parse_func.c.

927{
928 FuncCandidateList current_candidate;
929 FuncCandidateList next_candidate;
930 int ncandidates = 0;
931
932 *candidates = NULL;
933
934 for (current_candidate = raw_candidates;
935 current_candidate != NULL;
936 current_candidate = next_candidate)
937 {
938 next_candidate = current_candidate->next;
939 if (can_coerce_type(nargs, input_typeids, current_candidate->args,
941 {
942 current_candidate->next = *candidates;
943 *candidates = current_candidate;
944 ncandidates++;
945 }
946 }
947
948 return ncandidates;
949} /* func_match_argtypes() */
bool can_coerce_type(int nargs, const Oid *input_typeids, const Oid *target_typeids, CoercionContext ccontext)
Definition: parse_coerce.c:557
@ COERCION_IMPLICIT
Definition: primnodes.h:731

References _FuncCandidateList::args, can_coerce_type(), COERCION_IMPLICIT, and _FuncCandidateList::next.

Referenced by func_get_detail(), and oper_select_candidate().

◆ func_select_candidate()

FuncCandidateList func_select_candidate ( int  nargs,
Oid input_typeids,
FuncCandidateList  candidates 
)

Definition at line 1008 of file parse_func.c.

1011{
1012 FuncCandidateList current_candidate,
1013 first_candidate,
1014 last_candidate;
1015 Oid *current_typeids;
1016 Oid current_type;
1017 int i;
1018 int ncandidates;
1019 int nbestMatch,
1020 nmatch,
1021 nunknowns;
1022 Oid input_base_typeids[FUNC_MAX_ARGS];
1023 TYPCATEGORY slot_category[FUNC_MAX_ARGS],
1024 current_category;
1025 bool current_is_preferred;
1026 bool slot_has_preferred_type[FUNC_MAX_ARGS];
1027 bool resolved_unknowns;
1028
1029 /* protect local fixed-size arrays */
1030 if (nargs > FUNC_MAX_ARGS)
1031 ereport(ERROR,
1032 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
1033 errmsg_plural("cannot pass more than %d argument to a function",
1034 "cannot pass more than %d arguments to a function",
1036 FUNC_MAX_ARGS)));
1037
1038 /*
1039 * If any input types are domains, reduce them to their base types. This
1040 * ensures that we will consider functions on the base type to be "exact
1041 * matches" in the exact-match heuristic; it also makes it possible to do
1042 * something useful with the type-category heuristics. Note that this
1043 * makes it difficult, but not impossible, to use functions declared to
1044 * take a domain as an input datatype. Such a function will be selected
1045 * over the base-type function only if it is an exact match at all
1046 * argument positions, and so was already chosen by our caller.
1047 *
1048 * While we're at it, count the number of unknown-type arguments for use
1049 * later.
1050 */
1051 nunknowns = 0;
1052 for (i = 0; i < nargs; i++)
1053 {
1054 if (input_typeids[i] != UNKNOWNOID)
1055 input_base_typeids[i] = getBaseType(input_typeids[i]);
1056 else
1057 {
1058 /* no need to call getBaseType on UNKNOWNOID */
1059 input_base_typeids[i] = UNKNOWNOID;
1060 nunknowns++;
1061 }
1062 }
1063
1064 /*
1065 * Run through all candidates and keep those with the most matches on
1066 * exact types. Keep all candidates if none match.
1067 */
1068 ncandidates = 0;
1069 nbestMatch = 0;
1070 last_candidate = NULL;
1071 for (current_candidate = candidates;
1072 current_candidate != NULL;
1073 current_candidate = current_candidate->next)
1074 {
1075 current_typeids = current_candidate->args;
1076 nmatch = 0;
1077 for (i = 0; i < nargs; i++)
1078 {
1079 if (input_base_typeids[i] != UNKNOWNOID &&
1080 current_typeids[i] == input_base_typeids[i])
1081 nmatch++;
1082 }
1083
1084 /* take this one as the best choice so far? */
1085 if ((nmatch > nbestMatch) || (last_candidate == NULL))
1086 {
1087 nbestMatch = nmatch;
1088 candidates = current_candidate;
1089 last_candidate = current_candidate;
1090 ncandidates = 1;
1091 }
1092 /* no worse than the last choice, so keep this one too? */
1093 else if (nmatch == nbestMatch)
1094 {
1095 last_candidate->next = current_candidate;
1096 last_candidate = current_candidate;
1097 ncandidates++;
1098 }
1099 /* otherwise, don't bother keeping this one... */
1100 }
1101
1102 if (last_candidate) /* terminate rebuilt list */
1103 last_candidate->next = NULL;
1104
1105 if (ncandidates == 1)
1106 return candidates;
1107
1108 /*
1109 * Still too many candidates? Now look for candidates which have either
1110 * exact matches or preferred types at the args that will require
1111 * coercion. (Restriction added in 7.4: preferred type must be of same
1112 * category as input type; give no preference to cross-category
1113 * conversions to preferred types.) Keep all candidates if none match.
1114 */
1115 for (i = 0; i < nargs; i++) /* avoid multiple lookups */
1116 slot_category[i] = TypeCategory(input_base_typeids[i]);
1117 ncandidates = 0;
1118 nbestMatch = 0;
1119 last_candidate = NULL;
1120 for (current_candidate = candidates;
1121 current_candidate != NULL;
1122 current_candidate = current_candidate->next)
1123 {
1124 current_typeids = current_candidate->args;
1125 nmatch = 0;
1126 for (i = 0; i < nargs; i++)
1127 {
1128 if (input_base_typeids[i] != UNKNOWNOID)
1129 {
1130 if (current_typeids[i] == input_base_typeids[i] ||
1131 IsPreferredType(slot_category[i], current_typeids[i]))
1132 nmatch++;
1133 }
1134 }
1135
1136 if ((nmatch > nbestMatch) || (last_candidate == NULL))
1137 {
1138 nbestMatch = nmatch;
1139 candidates = current_candidate;
1140 last_candidate = current_candidate;
1141 ncandidates = 1;
1142 }
1143 else if (nmatch == nbestMatch)
1144 {
1145 last_candidate->next = current_candidate;
1146 last_candidate = current_candidate;
1147 ncandidates++;
1148 }
1149 }
1150
1151 if (last_candidate) /* terminate rebuilt list */
1152 last_candidate->next = NULL;
1153
1154 if (ncandidates == 1)
1155 return candidates;
1156
1157 /*
1158 * Still too many candidates? Try assigning types for the unknown inputs.
1159 *
1160 * If there are no unknown inputs, we have no more heuristics that apply,
1161 * and must fail.
1162 */
1163 if (nunknowns == 0)
1164 return NULL; /* failed to select a best candidate */
1165
1166 /*
1167 * The next step examines each unknown argument position to see if we can
1168 * determine a "type category" for it. If any candidate has an input
1169 * datatype of STRING category, use STRING category (this bias towards
1170 * STRING is appropriate since unknown-type literals look like strings).
1171 * Otherwise, if all the candidates agree on the type category of this
1172 * argument position, use that category. Otherwise, fail because we
1173 * cannot determine a category.
1174 *
1175 * If we are able to determine a type category, also notice whether any of
1176 * the candidates takes a preferred datatype within the category.
1177 *
1178 * Having completed this examination, remove candidates that accept the
1179 * wrong category at any unknown position. Also, if at least one
1180 * candidate accepted a preferred type at a position, remove candidates
1181 * that accept non-preferred types. If just one candidate remains, return
1182 * that one. However, if this rule turns out to reject all candidates,
1183 * keep them all instead.
1184 */
1185 resolved_unknowns = false;
1186 for (i = 0; i < nargs; i++)
1187 {
1188 bool have_conflict;
1189
1190 if (input_base_typeids[i] != UNKNOWNOID)
1191 continue;
1192 resolved_unknowns = true; /* assume we can do it */
1193 slot_category[i] = TYPCATEGORY_INVALID;
1194 slot_has_preferred_type[i] = false;
1195 have_conflict = false;
1196 for (current_candidate = candidates;
1197 current_candidate != NULL;
1198 current_candidate = current_candidate->next)
1199 {
1200 current_typeids = current_candidate->args;
1201 current_type = current_typeids[i];
1202 get_type_category_preferred(current_type,
1203 &current_category,
1204 &current_is_preferred);
1205 if (slot_category[i] == TYPCATEGORY_INVALID)
1206 {
1207 /* first candidate */
1208 slot_category[i] = current_category;
1209 slot_has_preferred_type[i] = current_is_preferred;
1210 }
1211 else if (current_category == slot_category[i])
1212 {
1213 /* more candidates in same category */
1214 slot_has_preferred_type[i] |= current_is_preferred;
1215 }
1216 else
1217 {
1218 /* category conflict! */
1219 if (current_category == TYPCATEGORY_STRING)
1220 {
1221 /* STRING always wins if available */
1222 slot_category[i] = current_category;
1223 slot_has_preferred_type[i] = current_is_preferred;
1224 }
1225 else
1226 {
1227 /*
1228 * Remember conflict, but keep going (might find STRING)
1229 */
1230 have_conflict = true;
1231 }
1232 }
1233 }
1234 if (have_conflict && slot_category[i] != TYPCATEGORY_STRING)
1235 {
1236 /* Failed to resolve category conflict at this position */
1237 resolved_unknowns = false;
1238 break;
1239 }
1240 }
1241
1242 if (resolved_unknowns)
1243 {
1244 /* Strip non-matching candidates */
1245 ncandidates = 0;
1246 first_candidate = candidates;
1247 last_candidate = NULL;
1248 for (current_candidate = candidates;
1249 current_candidate != NULL;
1250 current_candidate = current_candidate->next)
1251 {
1252 bool keepit = true;
1253
1254 current_typeids = current_candidate->args;
1255 for (i = 0; i < nargs; i++)
1256 {
1257 if (input_base_typeids[i] != UNKNOWNOID)
1258 continue;
1259 current_type = current_typeids[i];
1260 get_type_category_preferred(current_type,
1261 &current_category,
1262 &current_is_preferred);
1263 if (current_category != slot_category[i])
1264 {
1265 keepit = false;
1266 break;
1267 }
1268 if (slot_has_preferred_type[i] && !current_is_preferred)
1269 {
1270 keepit = false;
1271 break;
1272 }
1273 }
1274 if (keepit)
1275 {
1276 /* keep this candidate */
1277 last_candidate = current_candidate;
1278 ncandidates++;
1279 }
1280 else
1281 {
1282 /* forget this candidate */
1283 if (last_candidate)
1284 last_candidate->next = current_candidate->next;
1285 else
1286 first_candidate = current_candidate->next;
1287 }
1288 }
1289
1290 /* if we found any matches, restrict our attention to those */
1291 if (last_candidate)
1292 {
1293 candidates = first_candidate;
1294 /* terminate rebuilt list */
1295 last_candidate->next = NULL;
1296 }
1297
1298 if (ncandidates == 1)
1299 return candidates;
1300 }
1301
1302 /*
1303 * Last gasp: if there are both known- and unknown-type inputs, and all
1304 * the known types are the same, assume the unknown inputs are also that
1305 * type, and see if that gives us a unique match. If so, use that match.
1306 *
1307 * NOTE: for a binary operator with one unknown and one non-unknown input,
1308 * we already tried this heuristic in binary_oper_exact(). However, that
1309 * code only finds exact matches, whereas here we will handle matches that
1310 * involve coercion, polymorphic type resolution, etc.
1311 */
1312 if (nunknowns < nargs)
1313 {
1314 Oid known_type = UNKNOWNOID;
1315
1316 for (i = 0; i < nargs; i++)
1317 {
1318 if (input_base_typeids[i] == UNKNOWNOID)
1319 continue;
1320 if (known_type == UNKNOWNOID) /* first known arg? */
1321 known_type = input_base_typeids[i];
1322 else if (known_type != input_base_typeids[i])
1323 {
1324 /* oops, not all match */
1325 known_type = UNKNOWNOID;
1326 break;
1327 }
1328 }
1329
1330 if (known_type != UNKNOWNOID)
1331 {
1332 /* okay, just one known type, apply the heuristic */
1333 for (i = 0; i < nargs; i++)
1334 input_base_typeids[i] = known_type;
1335 ncandidates = 0;
1336 last_candidate = NULL;
1337 for (current_candidate = candidates;
1338 current_candidate != NULL;
1339 current_candidate = current_candidate->next)
1340 {
1341 current_typeids = current_candidate->args;
1342 if (can_coerce_type(nargs, input_base_typeids, current_typeids,
1344 {
1345 if (++ncandidates > 1)
1346 break; /* not unique, give up */
1347 last_candidate = current_candidate;
1348 }
1349 }
1350 if (ncandidates == 1)
1351 {
1352 /* successfully identified a unique match */
1353 last_candidate->next = NULL;
1354 return last_candidate;
1355 }
1356 }
1357 }
1358
1359 return NULL; /* failed to select a best candidate */
1360} /* func_select_candidate() */
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1180
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2548
void get_type_category_preferred(Oid typid, char *typcategory, bool *typispreferred)
Definition: lsyscache.c:2737
bool IsPreferredType(TYPCATEGORY category, Oid type)
char TYPCATEGORY
Definition: parse_coerce.h:21
#define FUNC_MAX_ARGS

References _FuncCandidateList::args, can_coerce_type(), COERCION_IMPLICIT, ereport, errcode(), errmsg_plural(), ERROR, FUNC_MAX_ARGS, get_type_category_preferred(), getBaseType(), i, IsPreferredType(), _FuncCandidateList::next, and TypeCategory().

Referenced by func_get_detail(), and oper_select_candidate().

◆ func_signature_string()

const char * func_signature_string ( List funcname,
int  nargs,
List argnames,
const Oid argtypes 
)

◆ funcname_signature_string()

const char * funcname_signature_string ( const char *  funcname,
int  nargs,
List argnames,
const Oid argtypes 
)

Definition at line 1993 of file parse_func.c.

1995{
1996 StringInfoData argbuf;
1997 int numposargs;
1998 ListCell *lc;
1999 int i;
2000
2001 initStringInfo(&argbuf);
2002
2003 appendStringInfo(&argbuf, "%s(", funcname);
2004
2005 numposargs = nargs - list_length(argnames);
2006 lc = list_head(argnames);
2007
2008 for (i = 0; i < nargs; i++)
2009 {
2010 if (i)
2011 appendStringInfoString(&argbuf, ", ");
2012 if (i >= numposargs)
2013 {
2014 appendStringInfo(&argbuf, "%s => ", (char *) lfirst(lc));
2015 lc = lnext(argnames, lc);
2016 }
2017 appendStringInfoString(&argbuf, format_type_be(argtypes[i]));
2018 }
2019
2020 appendStringInfoChar(&argbuf, ')');
2021
2022 return argbuf.data; /* return palloc'd string buffer */
2023}
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), StringInfoData::data, format_type_be(), funcname, i, initStringInfo(), lfirst, list_head(), list_length(), and lnext().

Referenced by func_signature_string(), and IsThereFunctionInNamespace().

◆ FuncNameAsType()

static Oid FuncNameAsType ( List funcname)
static

Definition at line 1881 of file parse_func.c.

1882{
1883 Oid result;
1884 Type typtup;
1885
1886 /*
1887 * temp_ok=false protects the <refsect1 id="sql-createfunction-security">
1888 * contract for writing SECURITY DEFINER functions safely.
1889 */
1891 NULL, false, false);
1892 if (typtup == NULL)
1893 return InvalidOid;
1894
1895 if (((Form_pg_type) GETSTRUCT(typtup))->typisdefined &&
1896 !OidIsValid(typeTypeRelid(typtup)))
1897 result = typeTypeId(typtup);
1898 else
1899 result = InvalidOid;
1900
1901 ReleaseSysCache(typtup);
1902 return result;
1903}
TypeName * makeTypeNameFromNameList(List *names)
Definition: makefuncs.c:484
Oid typeTypeRelid(Type typ)
Definition: parse_type.c:630
Type LookupTypeNameExtended(ParseState *pstate, const TypeName *typeName, int32 *typmod_p, bool temp_ok, bool missing_ok)
Definition: parse_type.c:73
Oid typeTypeId(Type tp)
Definition: parse_type.c:590
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261

References funcname, GETSTRUCT(), InvalidOid, LookupTypeNameExtended(), makeTypeNameFromNameList(), OidIsValid, ReleaseSysCache(), typeTypeId(), and typeTypeRelid().

Referenced by func_get_detail().

◆ LookupFuncName()

Oid LookupFuncName ( List funcname,
int  nargs,
const Oid argtypes,
bool  missing_ok 
)

Definition at line 2144 of file parse_func.c.

2145{
2146 Oid funcoid;
2147 FuncLookupError lookupError;
2148
2150 funcname, nargs, argtypes,
2151 false, missing_ok,
2152 &lookupError);
2153
2154 if (OidIsValid(funcoid))
2155 return funcoid;
2156
2157 switch (lookupError)
2158 {
2160 /* Let the caller deal with it when missing_ok is true */
2161 if (missing_ok)
2162 return InvalidOid;
2163
2164 if (nargs < 0)
2165 ereport(ERROR,
2166 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2167 errmsg("could not find a function named \"%s\"",
2169 else
2170 ereport(ERROR,
2171 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2172 errmsg("function %s does not exist",
2174 NIL, argtypes))));
2175 break;
2176
2178 /* Raise an error regardless of missing_ok */
2179 ereport(ERROR,
2180 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2181 errmsg("function name \"%s\" is not unique",
2183 errhint("Specify the argument list to select the function unambiguously.")));
2184 break;
2185 }
2186
2187 return InvalidOid; /* Keep compiler quiet */
2188}
int errhint(const char *fmt,...)
Definition: elog.c:1317
static Oid LookupFuncNameInternal(ObjectType objtype, List *funcname, int nargs, const Oid *argtypes, bool include_out_arguments, bool missing_ok, FuncLookupError *lookupError)
Definition: parse_func.c:2049
const char * func_signature_string(List *funcname, int nargs, List *argnames, const Oid *argtypes)
Definition: parse_func.c:2030
@ OBJECT_FUNCTION
Definition: parsenodes.h:2331

References ereport, errcode(), errhint(), errmsg(), ERROR, func_signature_string(), FUNCLOOKUP_AMBIGUOUS, FUNCLOOKUP_NOSUCHFUNC, funcname, InvalidOid, LookupFuncNameInternal(), NameListToString(), NIL, OBJECT_FUNCTION, and OidIsValid.

Referenced by call_pltcl_start_proc(), CreateConversionCommand(), CreateEventTrigger(), CreateProceduralLanguage(), CreateTriggerFiringOn(), DefineOperator(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), findTypeAnalyzeFunction(), findTypeInputFunction(), findTypeOutputFunction(), findTypeReceiveFunction(), findTypeSendFunction(), findTypeSubscriptingFunction(), findTypeTypmodinFunction(), findTypeTypmodoutFunction(), get_ts_parser_func(), get_ts_template_func(), interpret_func_support(), lookup_am_handler_func(), lookup_fdw_handler_func(), lookup_fdw_validator_func(), transformRangeTableSample(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

◆ LookupFuncNameInternal()

static Oid LookupFuncNameInternal ( ObjectType  objtype,
List funcname,
int  nargs,
const Oid argtypes,
bool  include_out_arguments,
bool  missing_ok,
FuncLookupError lookupError 
)
static

Definition at line 2049 of file parse_func.c.

2053{
2054 Oid result = InvalidOid;
2055 FuncCandidateList clist;
2056
2057 /* NULL argtypes allowed for nullary functions only */
2058 Assert(argtypes != NULL || nargs == 0);
2059
2060 /* Always set *lookupError, to forestall uninitialized-variable warnings */
2061 *lookupError = FUNCLOOKUP_NOSUCHFUNC;
2062
2063 /* Get list of candidate objects */
2064 clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false,
2065 include_out_arguments, missing_ok);
2066
2067 /* Scan list for a match to the arg types (if specified) and the objtype */
2068 for (; clist != NULL; clist = clist->next)
2069 {
2070 /* Check arg type match, if specified */
2071 if (nargs >= 0)
2072 {
2073 /* if nargs==0, argtypes can be null; don't pass that to memcmp */
2074 if (nargs > 0 &&
2075 memcmp(argtypes, clist->args, nargs * sizeof(Oid)) != 0)
2076 continue;
2077 }
2078
2079 /* Check for duplicates reported by FuncnameGetCandidates */
2080 if (!OidIsValid(clist->oid))
2081 {
2082 *lookupError = FUNCLOOKUP_AMBIGUOUS;
2083 return InvalidOid;
2084 }
2085
2086 /* Check objtype match, if specified */
2087 switch (objtype)
2088 {
2089 case OBJECT_FUNCTION:
2090 case OBJECT_AGGREGATE:
2091 /* Ignore procedures */
2092 if (get_func_prokind(clist->oid) == PROKIND_PROCEDURE)
2093 continue;
2094 break;
2095 case OBJECT_PROCEDURE:
2096 /* Ignore non-procedures */
2097 if (get_func_prokind(clist->oid) != PROKIND_PROCEDURE)
2098 continue;
2099 break;
2100 case OBJECT_ROUTINE:
2101 /* no restriction */
2102 break;
2103 default:
2104 Assert(false);
2105 }
2106
2107 /* Check for multiple matches */
2108 if (OidIsValid(result))
2109 {
2110 *lookupError = FUNCLOOKUP_AMBIGUOUS;
2111 return InvalidOid;
2112 }
2113
2114 /* OK, we have a candidate */
2115 result = clist->oid;
2116 }
2117
2118 return result;
2119}
char get_func_prokind(Oid funcid)
Definition: lsyscache.c:1845
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2313
@ OBJECT_ROUTINE
Definition: parsenodes.h:2346
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2341

References _FuncCandidateList::args, Assert, FUNCLOOKUP_AMBIGUOUS, FUNCLOOKUP_NOSUCHFUNC, funcname, FuncnameGetCandidates(), get_func_prokind(), InvalidOid, _FuncCandidateList::next, NIL, OBJECT_AGGREGATE, OBJECT_FUNCTION, OBJECT_PROCEDURE, OBJECT_ROUTINE, _FuncCandidateList::oid, and OidIsValid.

Referenced by LookupFuncName(), and LookupFuncWithArgs().

◆ LookupFuncWithArgs()

Oid LookupFuncWithArgs ( ObjectType  objtype,
ObjectWithArgs func,
bool  missing_ok 
)

Definition at line 2206 of file parse_func.c.

2207{
2208 Oid argoids[FUNC_MAX_ARGS];
2209 int argcount;
2210 int nargs;
2211 int i;
2212 ListCell *args_item;
2213 Oid oid;
2214 FuncLookupError lookupError;
2215
2216 Assert(objtype == OBJECT_AGGREGATE ||
2217 objtype == OBJECT_FUNCTION ||
2218 objtype == OBJECT_PROCEDURE ||
2219 objtype == OBJECT_ROUTINE);
2220
2221 argcount = list_length(func->objargs);
2222 if (argcount > FUNC_MAX_ARGS)
2223 {
2224 if (objtype == OBJECT_PROCEDURE)
2225 ereport(ERROR,
2226 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2227 errmsg_plural("procedures cannot have more than %d argument",
2228 "procedures cannot have more than %d arguments",
2230 FUNC_MAX_ARGS)));
2231 else
2232 ereport(ERROR,
2233 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
2234 errmsg_plural("functions cannot have more than %d argument",
2235 "functions cannot have more than %d arguments",
2237 FUNC_MAX_ARGS)));
2238 }
2239
2240 /*
2241 * First, perform a lookup considering only input arguments (traditional
2242 * Postgres rules).
2243 */
2244 i = 0;
2245 foreach(args_item, func->objargs)
2246 {
2247 TypeName *t = lfirst_node(TypeName, args_item);
2248
2249 argoids[i] = LookupTypeNameOid(NULL, t, missing_ok);
2250 if (!OidIsValid(argoids[i]))
2251 return InvalidOid; /* missing_ok must be true */
2252 i++;
2253 }
2254
2255 /*
2256 * Set nargs for LookupFuncNameInternal. It expects -1 to mean no args
2257 * were specified.
2258 */
2259 nargs = func->args_unspecified ? -1 : argcount;
2260
2261 /*
2262 * In args_unspecified mode, also tell LookupFuncNameInternal to consider
2263 * the object type, since there seems no reason not to. However, if we
2264 * have an argument list, disable the objtype check, because we'd rather
2265 * complain about "object is of wrong type" than "object doesn't exist".
2266 * (Note that with args, FuncnameGetCandidates will have ensured there's
2267 * only one argtype match, so we're not risking an ambiguity failure via
2268 * this choice.)
2269 */
2271 func->objname, nargs, argoids,
2272 false, missing_ok,
2273 &lookupError);
2274
2275 /*
2276 * If PROCEDURE or ROUTINE was specified, and we have an argument list
2277 * that contains no parameter mode markers, and we didn't already discover
2278 * that there's ambiguity, perform a lookup considering all arguments.
2279 * (Note: for a zero-argument procedure, or in args_unspecified mode, the
2280 * normal lookup is sufficient; so it's OK to require non-NIL objfuncargs
2281 * to perform this lookup.)
2282 */
2283 if ((objtype == OBJECT_PROCEDURE || objtype == OBJECT_ROUTINE) &&
2284 func->objfuncargs != NIL &&
2285 lookupError != FUNCLOOKUP_AMBIGUOUS)
2286 {
2287 bool have_param_mode = false;
2288
2289 /*
2290 * Check for non-default parameter mode markers. If there are any,
2291 * then the command does not conform to SQL-spec syntax, so we may
2292 * assume that the traditional Postgres lookup method of considering
2293 * only input parameters is sufficient. (Note that because the spec
2294 * doesn't have OUT arguments for functions, we also don't need this
2295 * hack in FUNCTION or AGGREGATE mode.)
2296 */
2297 foreach(args_item, func->objfuncargs)
2298 {
2300
2301 if (fp->mode != FUNC_PARAM_DEFAULT)
2302 {
2303 have_param_mode = true;
2304 break;
2305 }
2306 }
2307
2308 if (!have_param_mode)
2309 {
2310 Oid poid;
2311
2312 /* Without mode marks, objargs surely includes all params */
2313 Assert(list_length(func->objfuncargs) == argcount);
2314
2315 /* For objtype == OBJECT_PROCEDURE, we can ignore non-procedures */
2316 poid = LookupFuncNameInternal(objtype, func->objname,
2317 argcount, argoids,
2318 true, missing_ok,
2319 &lookupError);
2320
2321 /* Combine results, handling ambiguity */
2322 if (OidIsValid(poid))
2323 {
2324 if (OidIsValid(oid) && oid != poid)
2325 {
2326 /* oops, we got hits both ways, on different objects */
2327 oid = InvalidOid;
2328 lookupError = FUNCLOOKUP_AMBIGUOUS;
2329 }
2330 else
2331 oid = poid;
2332 }
2333 else if (lookupError == FUNCLOOKUP_AMBIGUOUS)
2334 oid = InvalidOid;
2335 }
2336 }
2337
2338 if (OidIsValid(oid))
2339 {
2340 /*
2341 * Even if we found the function, perform validation that the objtype
2342 * matches the prokind of the found function. For historical reasons
2343 * we allow the objtype of FUNCTION to include aggregates and window
2344 * functions; but we draw the line if the object is a procedure. That
2345 * is a new enough feature that this historical rule does not apply.
2346 *
2347 * (This check is partially redundant with the objtype check in
2348 * LookupFuncNameInternal; but not entirely, since we often don't tell
2349 * LookupFuncNameInternal to apply that check at all.)
2350 */
2351 switch (objtype)
2352 {
2353 case OBJECT_FUNCTION:
2354 /* Only complain if it's a procedure. */
2355 if (get_func_prokind(oid) == PROKIND_PROCEDURE)
2356 ereport(ERROR,
2357 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2358 errmsg("%s is not a function",
2359 func_signature_string(func->objname, argcount,
2360 NIL, argoids))));
2361 break;
2362
2363 case OBJECT_PROCEDURE:
2364 /* Reject if found object is not a procedure. */
2365 if (get_func_prokind(oid) != PROKIND_PROCEDURE)
2366 ereport(ERROR,
2367 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2368 errmsg("%s is not a procedure",
2369 func_signature_string(func->objname, argcount,
2370 NIL, argoids))));
2371 break;
2372
2373 case OBJECT_AGGREGATE:
2374 /* Reject if found object is not an aggregate. */
2375 if (get_func_prokind(oid) != PROKIND_AGGREGATE)
2376 ereport(ERROR,
2377 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2378 errmsg("function %s is not an aggregate",
2379 func_signature_string(func->objname, argcount,
2380 NIL, argoids))));
2381 break;
2382
2383 default:
2384 /* OBJECT_ROUTINE accepts anything. */
2385 break;
2386 }
2387
2388 return oid; /* All good */
2389 }
2390 else
2391 {
2392 /* Deal with cases where the lookup failed */
2393 switch (lookupError)
2394 {
2396 /* Suppress no-such-func errors when missing_ok is true */
2397 if (missing_ok)
2398 break;
2399
2400 switch (objtype)
2401 {
2402 case OBJECT_PROCEDURE:
2403 if (func->args_unspecified)
2404 ereport(ERROR,
2405 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2406 errmsg("could not find a procedure named \"%s\"",
2407 NameListToString(func->objname))));
2408 else
2409 ereport(ERROR,
2410 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2411 errmsg("procedure %s does not exist",
2412 func_signature_string(func->objname, argcount,
2413 NIL, argoids))));
2414 break;
2415
2416 case OBJECT_AGGREGATE:
2417 if (func->args_unspecified)
2418 ereport(ERROR,
2419 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2420 errmsg("could not find an aggregate named \"%s\"",
2421 NameListToString(func->objname))));
2422 else if (argcount == 0)
2423 ereport(ERROR,
2424 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2425 errmsg("aggregate %s(*) does not exist",
2426 NameListToString(func->objname))));
2427 else
2428 ereport(ERROR,
2429 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2430 errmsg("aggregate %s does not exist",
2431 func_signature_string(func->objname, argcount,
2432 NIL, argoids))));
2433 break;
2434
2435 default:
2436 /* FUNCTION and ROUTINE */
2437 if (func->args_unspecified)
2438 ereport(ERROR,
2439 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2440 errmsg("could not find a function named \"%s\"",
2441 NameListToString(func->objname))));
2442 else
2443 ereport(ERROR,
2444 (errcode(ERRCODE_UNDEFINED_FUNCTION),
2445 errmsg("function %s does not exist",
2446 func_signature_string(func->objname, argcount,
2447 NIL, argoids))));
2448 break;
2449 }
2450 break;
2451
2453 switch (objtype)
2454 {
2455 case OBJECT_FUNCTION:
2456 ereport(ERROR,
2457 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2458 errmsg("function name \"%s\" is not unique",
2459 NameListToString(func->objname)),
2460 func->args_unspecified ?
2461 errhint("Specify the argument list to select the function unambiguously.") : 0));
2462 break;
2463 case OBJECT_PROCEDURE:
2464 ereport(ERROR,
2465 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2466 errmsg("procedure name \"%s\" is not unique",
2467 NameListToString(func->objname)),
2468 func->args_unspecified ?
2469 errhint("Specify the argument list to select the procedure unambiguously.") : 0));
2470 break;
2471 case OBJECT_AGGREGATE:
2472 ereport(ERROR,
2473 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2474 errmsg("aggregate name \"%s\" is not unique",
2475 NameListToString(func->objname)),
2476 func->args_unspecified ?
2477 errhint("Specify the argument list to select the aggregate unambiguously.") : 0));
2478 break;
2479 case OBJECT_ROUTINE:
2480 ereport(ERROR,
2481 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
2482 errmsg("routine name \"%s\" is not unique",
2483 NameListToString(func->objname)),
2484 func->args_unspecified ?
2485 errhint("Specify the argument list to select the routine unambiguously.") : 0));
2486 break;
2487
2488 default:
2489 Assert(false); /* Disallowed by Assert above */
2490 break;
2491 }
2492 break;
2493 }
2494
2495 return InvalidOid;
2496 }
2497}
Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok)
Definition: parse_type.c:232
@ FUNC_PARAM_DEFAULT
Definition: parsenodes.h:3523
#define lfirst_node(type, lc)
Definition: pg_list.h:176
FunctionParameterMode mode
Definition: parsenodes.h:3531
List * objfuncargs
Definition: parsenodes.h:2582
bool args_unspecified
Definition: parsenodes.h:2583

References ObjectWithArgs::args_unspecified, Assert, ereport, errcode(), errhint(), errmsg(), errmsg_plural(), ERROR, FUNC_MAX_ARGS, FUNC_PARAM_DEFAULT, func_signature_string(), FUNCLOOKUP_AMBIGUOUS, FUNCLOOKUP_NOSUCHFUNC, get_func_prokind(), i, InvalidOid, lfirst_node, list_length(), LookupFuncNameInternal(), LookupTypeNameOid(), FunctionParameter::mode, NameListToString(), NIL, ObjectWithArgs::objargs, OBJECT_AGGREGATE, OBJECT_FUNCTION, OBJECT_PROCEDURE, OBJECT_ROUTINE, ObjectWithArgs::objfuncargs, ObjectWithArgs::objname, and OidIsValid.

Referenced by AlterFunction(), AlterOpFamilyAdd(), CreateCast(), CreateTransform(), DefineOpClass(), and get_object_address().

◆ make_fn_arguments()

void make_fn_arguments ( ParseState pstate,
List fargs,
Oid actual_arg_types,
Oid declared_arg_types 
)

Definition at line 1825 of file parse_func.c.

1829{
1830 ListCell *current_fargs;
1831 int i = 0;
1832
1833 foreach(current_fargs, fargs)
1834 {
1835 /* types don't match? then force coercion using a function call... */
1836 if (actual_arg_types[i] != declared_arg_types[i])
1837 {
1838 Node *node = (Node *) lfirst(current_fargs);
1839
1840 /*
1841 * If arg is a NamedArgExpr, coerce its input expr instead --- we
1842 * want the NamedArgExpr to stay at the top level of the list.
1843 */
1844 if (IsA(node, NamedArgExpr))
1845 {
1846 NamedArgExpr *na = (NamedArgExpr *) node;
1847
1848 node = coerce_type(pstate,
1849 (Node *) na->arg,
1850 actual_arg_types[i],
1851 declared_arg_types[i], -1,
1854 -1);
1855 na->arg = (Expr *) node;
1856 }
1857 else
1858 {
1859 node = coerce_type(pstate,
1860 node,
1861 actual_arg_types[i],
1862 declared_arg_types[i], -1,
1865 -1);
1866 lfirst(current_fargs) = node;
1867 }
1868 }
1869 i++;
1870 }
1871}
Node * coerce_type(ParseState *pstate, Node *node, Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod, CoercionContext ccontext, CoercionForm cformat, int location)
Definition: parse_coerce.c:157
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:753
Expr * arg
Definition: primnodes.h:808

References NamedArgExpr::arg, COERCE_IMPLICIT_CAST, coerce_type(), COERCION_IMPLICIT, i, IsA, and lfirst.

Referenced by make_op(), make_scalar_array_op(), ParseFuncOrColumn(), and recheck_cast_function_args().

◆ ParseComplexProjection()

static Node * ParseComplexProjection ( ParseState pstate,
const char *  funcname,
Node first_arg,
int  location 
)
static

Definition at line 1912 of file parse_func.c.

1914{
1915 TupleDesc tupdesc;
1916 int i;
1917
1918 /*
1919 * Special case for whole-row Vars so that we can resolve (foo.*).bar even
1920 * when foo is a reference to a subselect, join, or RECORD function. A
1921 * bonus is that we avoid generating an unnecessary FieldSelect; our
1922 * result can omit the whole-row Var and just be a Var for the selected
1923 * field.
1924 *
1925 * This case could be handled by expandRecordVariable, but it's more
1926 * efficient to do it this way when possible.
1927 */
1928 if (IsA(first_arg, Var) &&
1929 ((Var *) first_arg)->varattno == InvalidAttrNumber)
1930 {
1931 ParseNamespaceItem *nsitem;
1932
1933 nsitem = GetNSItemByRangeTablePosn(pstate,
1934 ((Var *) first_arg)->varno,
1935 ((Var *) first_arg)->varlevelsup);
1936 /* Return a Var if funcname matches a column, else NULL */
1937 return scanNSItemForColumn(pstate, nsitem,
1938 ((Var *) first_arg)->varlevelsup,
1939 funcname, location);
1940 }
1941
1942 /*
1943 * Else do it the hard way with get_expr_result_tupdesc().
1944 *
1945 * If it's a Var of type RECORD, we have to work even harder: we have to
1946 * find what the Var refers to, and pass that to get_expr_result_tupdesc.
1947 * That task is handled by expandRecordVariable().
1948 */
1949 if (IsA(first_arg, Var) &&
1950 ((Var *) first_arg)->vartype == RECORDOID)
1951 tupdesc = expandRecordVariable(pstate, (Var *) first_arg, 0);
1952 else
1953 tupdesc = get_expr_result_tupdesc(first_arg, true);
1954 if (!tupdesc)
1955 return NULL; /* unresolvable RECORD type */
1956
1957 for (i = 0; i < tupdesc->natts; i++)
1958 {
1959 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1960
1961 if (strcmp(funcname, NameStr(att->attname)) == 0 &&
1962 !att->attisdropped)
1963 {
1964 /* Success, so generate a FieldSelect expression */
1965 FieldSelect *fselect = makeNode(FieldSelect);
1966
1967 fselect->arg = (Expr *) first_arg;
1968 fselect->fieldnum = i + 1;
1969 fselect->resulttype = att->atttypid;
1970 fselect->resulttypmod = att->atttypmod;
1971 /* save attribute's collation for parse_collate.c */
1972 fselect->resultcollid = att->attcollation;
1973 return (Node *) fselect;
1974 }
1975 }
1976
1977 return NULL; /* funcname does not match any column */
1978}
#define InvalidAttrNumber
Definition: attnum.h:23
#define NameStr(name)
Definition: c.h:703
TupleDesc get_expr_result_tupdesc(Node *expr, bool noError)
Definition: funcapi.c:551
#define makeNode(_type_)
Definition: nodes.h:155
ParseNamespaceItem * GetNSItemByRangeTablePosn(ParseState *pstate, int varno, int sublevels_up)
Node * scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, const char *colname, int location)
TupleDesc expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
AttrNumber fieldnum
Definition: primnodes.h:1146
Expr * arg
Definition: primnodes.h:1145
Definition: primnodes.h:262
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:154

References FieldSelect::arg, expandRecordVariable(), FieldSelect::fieldnum, funcname, get_expr_result_tupdesc(), GetNSItemByRangeTablePosn(), i, InvalidAttrNumber, IsA, makeNode, NameStr, TupleDescData::natts, scanNSItemForColumn(), and TupleDescAttr().

Referenced by ParseFuncOrColumn().

◆ ParseFuncOrColumn()

Node * ParseFuncOrColumn ( ParseState pstate,
List funcname,
List fargs,
Node last_srf,
FuncCall fn,
bool  proc_call,
int  location 
)

Definition at line 90 of file parse_func.c.

92{
93 bool is_column = (fn == NULL);
94 List *agg_order = (fn ? fn->agg_order : NIL);
95 Expr *agg_filter = NULL;
96 WindowDef *over = (fn ? fn->over : NULL);
97 bool agg_within_group = (fn ? fn->agg_within_group : false);
98 bool agg_star = (fn ? fn->agg_star : false);
99 bool agg_distinct = (fn ? fn->agg_distinct : false);
100 bool func_variadic = (fn ? fn->func_variadic : false);
101 CoercionForm funcformat = (fn ? fn->funcformat : COERCE_EXPLICIT_CALL);
102 bool could_be_projection;
103 Oid rettype;
104 Oid funcid;
105 ListCell *l;
106 Node *first_arg = NULL;
107 int nargs;
108 int nargsplusdefs;
109 Oid actual_arg_types[FUNC_MAX_ARGS];
110 Oid *declared_arg_types;
111 List *argnames;
112 List *argdefaults;
113 Node *retval;
114 bool retset;
115 int nvargs;
116 Oid vatype;
117 FuncDetailCode fdresult;
118 char aggkind = 0;
119 ParseCallbackState pcbstate;
120
121 /*
122 * If there's an aggregate filter, transform it using transformWhereClause
123 */
124 if (fn && fn->agg_filter != NULL)
125 agg_filter = (Expr *) transformWhereClause(pstate, fn->agg_filter,
127 "FILTER");
128
129 /*
130 * Most of the rest of the parser just assumes that functions do not have
131 * more than FUNC_MAX_ARGS parameters. We have to test here to protect
132 * against array overruns, etc. Of course, this may not be a function,
133 * but the test doesn't hurt.
134 */
135 if (list_length(fargs) > FUNC_MAX_ARGS)
137 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
138 errmsg_plural("cannot pass more than %d argument to a function",
139 "cannot pass more than %d arguments to a function",
142 parser_errposition(pstate, location)));
143
144 /*
145 * Extract arg type info in preparation for function lookup.
146 *
147 * If any arguments are Param markers of type VOID, we discard them from
148 * the parameter list. This is a hack to allow the JDBC driver to not have
149 * to distinguish "input" and "output" parameter symbols while parsing
150 * function-call constructs. Don't do this if dealing with column syntax,
151 * nor if we had WITHIN GROUP (because in that case it's critical to keep
152 * the argument count unchanged).
153 */
154 nargs = 0;
155 foreach(l, fargs)
156 {
157 Node *arg = lfirst(l);
158 Oid argtype = exprType(arg);
159
160 if (argtype == VOIDOID && IsA(arg, Param) &&
161 !is_column && !agg_within_group)
162 {
163 fargs = foreach_delete_current(fargs, l);
164 continue;
165 }
166
167 actual_arg_types[nargs++] = argtype;
168 }
169
170 /*
171 * Check for named arguments; if there are any, build a list of names.
172 *
173 * We allow mixed notation (some named and some not), but only with all
174 * the named parameters after all the unnamed ones. So the name list
175 * corresponds to the last N actual parameters and we don't need any extra
176 * bookkeeping to match things up.
177 */
178 argnames = NIL;
179 foreach(l, fargs)
180 {
181 Node *arg = lfirst(l);
182
183 if (IsA(arg, NamedArgExpr))
184 {
185 NamedArgExpr *na = (NamedArgExpr *) arg;
186 ListCell *lc;
187
188 /* Reject duplicate arg names */
189 foreach(lc, argnames)
190 {
191 if (strcmp(na->name, (char *) lfirst(lc)) == 0)
193 (errcode(ERRCODE_SYNTAX_ERROR),
194 errmsg("argument name \"%s\" used more than once",
195 na->name),
196 parser_errposition(pstate, na->location)));
197 }
198 argnames = lappend(argnames, na->name);
199 }
200 else
201 {
202 if (argnames != NIL)
204 (errcode(ERRCODE_SYNTAX_ERROR),
205 errmsg("positional argument cannot follow named argument"),
207 }
208 }
209
210 if (fargs)
211 {
212 first_arg = linitial(fargs);
213 Assert(first_arg != NULL);
214 }
215
216 /*
217 * Decide whether it's legitimate to consider the construct to be a column
218 * projection. For that, there has to be a single argument of complex
219 * type, the function name must not be qualified, and there cannot be any
220 * syntactic decoration that'd require it to be a function (such as
221 * aggregate or variadic decoration, or named arguments).
222 */
223 could_be_projection = (nargs == 1 && !proc_call &&
224 agg_order == NIL && agg_filter == NULL &&
225 !agg_star && !agg_distinct && over == NULL &&
226 !func_variadic && argnames == NIL &&
227 list_length(funcname) == 1 &&
228 (actual_arg_types[0] == RECORDOID ||
229 ISCOMPLEX(actual_arg_types[0])));
230
231 /*
232 * If it's column syntax, check for column projection case first.
233 */
234 if (could_be_projection && is_column)
235 {
236 retval = ParseComplexProjection(pstate,
238 first_arg,
239 location);
240 if (retval)
241 return retval;
242
243 /*
244 * If ParseComplexProjection doesn't recognize it as a projection,
245 * just press on.
246 */
247 }
248
249 /*
250 * func_get_detail looks up the function in the catalogs, does
251 * disambiguation for polymorphic functions, handles inheritance, and
252 * returns the funcid and type and set or singleton status of the
253 * function's return value. It also returns the true argument types to
254 * the function.
255 *
256 * Note: for a named-notation or variadic function call, the reported
257 * "true" types aren't really what is in pg_proc: the types are reordered
258 * to match the given argument order of named arguments, and a variadic
259 * argument is replaced by a suitable number of copies of its element
260 * type. We'll fix up the variadic case below. We may also have to deal
261 * with default arguments.
262 */
263
264 setup_parser_errposition_callback(&pcbstate, pstate, location);
265
266 fdresult = func_get_detail(funcname, fargs, argnames, nargs,
267 actual_arg_types,
268 !func_variadic, true, proc_call,
269 &funcid, &rettype, &retset,
270 &nvargs, &vatype,
271 &declared_arg_types, &argdefaults);
272
274
275 /*
276 * Check for various wrong-kind-of-routine cases.
277 */
278
279 /* If this is a CALL, reject things that aren't procedures */
280 if (proc_call &&
281 (fdresult == FUNCDETAIL_NORMAL ||
282 fdresult == FUNCDETAIL_AGGREGATE ||
283 fdresult == FUNCDETAIL_WINDOWFUNC ||
284 fdresult == FUNCDETAIL_COERCION))
286 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
287 errmsg("%s is not a procedure",
289 argnames,
290 actual_arg_types)),
291 errhint("To call a function, use SELECT."),
292 parser_errposition(pstate, location)));
293 /* Conversely, if not a CALL, reject procedures */
294 if (fdresult == FUNCDETAIL_PROCEDURE && !proc_call)
296 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
297 errmsg("%s is a procedure",
299 argnames,
300 actual_arg_types)),
301 errhint("To call a procedure, use CALL."),
302 parser_errposition(pstate, location)));
303
304 if (fdresult == FUNCDETAIL_NORMAL ||
305 fdresult == FUNCDETAIL_PROCEDURE ||
306 fdresult == FUNCDETAIL_COERCION)
307 {
308 /*
309 * In these cases, complain if there was anything indicating it must
310 * be an aggregate or window function.
311 */
312 if (agg_star)
314 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
315 errmsg("%s(*) specified, but %s is not an aggregate function",
318 parser_errposition(pstate, location)));
319 if (agg_distinct)
321 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
322 errmsg("DISTINCT specified, but %s is not an aggregate function",
324 parser_errposition(pstate, location)));
325 if (agg_within_group)
327 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
328 errmsg("WITHIN GROUP specified, but %s is not an aggregate function",
330 parser_errposition(pstate, location)));
331 if (agg_order != NIL)
333 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
334 errmsg("ORDER BY specified, but %s is not an aggregate function",
336 parser_errposition(pstate, location)));
337 if (agg_filter)
339 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
340 errmsg("FILTER specified, but %s is not an aggregate function",
342 parser_errposition(pstate, location)));
343 if (over)
345 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
346 errmsg("OVER specified, but %s is not a window function nor an aggregate function",
348 parser_errposition(pstate, location)));
349 }
350
351 /*
352 * So far so good, so do some fdresult-type-specific processing.
353 */
354 if (fdresult == FUNCDETAIL_NORMAL || fdresult == FUNCDETAIL_PROCEDURE)
355 {
356 /* Nothing special to do for these cases. */
357 }
358 else if (fdresult == FUNCDETAIL_AGGREGATE)
359 {
360 /*
361 * It's an aggregate; fetch needed info from the pg_aggregate entry.
362 */
363 HeapTuple tup;
364 Form_pg_aggregate classForm;
365 int catDirectArgs;
366
367 tup = SearchSysCache1(AGGFNOID, ObjectIdGetDatum(funcid));
368 if (!HeapTupleIsValid(tup)) /* should not happen */
369 elog(ERROR, "cache lookup failed for aggregate %u", funcid);
370 classForm = (Form_pg_aggregate) GETSTRUCT(tup);
371 aggkind = classForm->aggkind;
372 catDirectArgs = classForm->aggnumdirectargs;
373 ReleaseSysCache(tup);
374
375 /* Now check various disallowed cases. */
376 if (AGGKIND_IS_ORDERED_SET(aggkind))
377 {
378 int numAggregatedArgs;
379 int numDirectArgs;
380
381 if (!agg_within_group)
383 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
384 errmsg("WITHIN GROUP is required for ordered-set aggregate %s",
386 parser_errposition(pstate, location)));
387 if (over)
389 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
390 errmsg("OVER is not supported for ordered-set aggregate %s",
392 parser_errposition(pstate, location)));
393 /* gram.y rejects DISTINCT + WITHIN GROUP */
394 Assert(!agg_distinct);
395 /* gram.y rejects VARIADIC + WITHIN GROUP */
396 Assert(!func_variadic);
397
398 /*
399 * Since func_get_detail was working with an undifferentiated list
400 * of arguments, it might have selected an aggregate that doesn't
401 * really match because it requires a different division of direct
402 * and aggregated arguments. Check that the number of direct
403 * arguments is actually OK; if not, throw an "undefined function"
404 * error, similarly to the case where a misplaced ORDER BY is used
405 * in a regular aggregate call.
406 */
407 numAggregatedArgs = list_length(agg_order);
408 numDirectArgs = nargs - numAggregatedArgs;
409 Assert(numDirectArgs >= 0);
410
411 if (!OidIsValid(vatype))
412 {
413 /* Test is simple if aggregate isn't variadic */
414 if (numDirectArgs != catDirectArgs)
416 (errcode(ERRCODE_UNDEFINED_FUNCTION),
417 errmsg("function %s does not exist",
419 argnames,
420 actual_arg_types)),
421 errhint_plural("There is an ordered-set aggregate %s, but it requires %d direct argument, not %d.",
422 "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d.",
423 catDirectArgs,
425 catDirectArgs, numDirectArgs),
426 parser_errposition(pstate, location)));
427 }
428 else
429 {
430 /*
431 * If it's variadic, we have two cases depending on whether
432 * the agg was "... ORDER BY VARIADIC" or "..., VARIADIC ORDER
433 * BY VARIADIC". It's the latter if catDirectArgs equals
434 * pronargs; to save a catalog lookup, we reverse-engineer
435 * pronargs from the info we got from func_get_detail.
436 */
437 int pronargs;
438
439 pronargs = nargs;
440 if (nvargs > 1)
441 pronargs -= nvargs - 1;
442 if (catDirectArgs < pronargs)
443 {
444 /* VARIADIC isn't part of direct args, so still easy */
445 if (numDirectArgs != catDirectArgs)
447 (errcode(ERRCODE_UNDEFINED_FUNCTION),
448 errmsg("function %s does not exist",
450 argnames,
451 actual_arg_types)),
452 errhint_plural("There is an ordered-set aggregate %s, but it requires %d direct argument, not %d.",
453 "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d.",
454 catDirectArgs,
456 catDirectArgs, numDirectArgs),
457 parser_errposition(pstate, location)));
458 }
459 else
460 {
461 /*
462 * Both direct and aggregated args were declared variadic.
463 * For a standard ordered-set aggregate, it's okay as long
464 * as there aren't too few direct args. For a
465 * hypothetical-set aggregate, we assume that the
466 * hypothetical arguments are those that matched the
467 * variadic parameter; there must be just as many of them
468 * as there are aggregated arguments.
469 */
470 if (aggkind == AGGKIND_HYPOTHETICAL)
471 {
472 if (nvargs != 2 * numAggregatedArgs)
474 (errcode(ERRCODE_UNDEFINED_FUNCTION),
475 errmsg("function %s does not exist",
477 argnames,
478 actual_arg_types)),
479 errhint("To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d).",
481 nvargs - numAggregatedArgs, numAggregatedArgs),
482 parser_errposition(pstate, location)));
483 }
484 else
485 {
486 if (nvargs <= numAggregatedArgs)
488 (errcode(ERRCODE_UNDEFINED_FUNCTION),
489 errmsg("function %s does not exist",
491 argnames,
492 actual_arg_types)),
493 errhint_plural("There is an ordered-set aggregate %s, but it requires at least %d direct argument.",
494 "There is an ordered-set aggregate %s, but it requires at least %d direct arguments.",
495 catDirectArgs,
497 catDirectArgs),
498 parser_errposition(pstate, location)));
499 }
500 }
501 }
502
503 /* Check type matching of hypothetical arguments */
504 if (aggkind == AGGKIND_HYPOTHETICAL)
505 unify_hypothetical_args(pstate, fargs, numAggregatedArgs,
506 actual_arg_types, declared_arg_types);
507 }
508 else
509 {
510 /* Normal aggregate, so it can't have WITHIN GROUP */
511 if (agg_within_group)
513 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
514 errmsg("%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP",
516 parser_errposition(pstate, location)));
517 }
518 }
519 else if (fdresult == FUNCDETAIL_WINDOWFUNC)
520 {
521 /*
522 * True window functions must be called with a window definition.
523 */
524 if (!over)
526 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
527 errmsg("window function %s requires an OVER clause",
529 parser_errposition(pstate, location)));
530 /* And, per spec, WITHIN GROUP isn't allowed */
531 if (agg_within_group)
533 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
534 errmsg("window function %s cannot have WITHIN GROUP",
536 parser_errposition(pstate, location)));
537 }
538 else if (fdresult == FUNCDETAIL_COERCION)
539 {
540 /*
541 * We interpreted it as a type coercion. coerce_type can handle these
542 * cases, so why duplicate code...
543 */
544 return coerce_type(pstate, linitial(fargs),
545 actual_arg_types[0], rettype, -1,
547 }
548 else if (fdresult == FUNCDETAIL_MULTIPLE)
549 {
550 /*
551 * We found multiple possible functional matches. If we are dealing
552 * with attribute notation, return failure, letting the caller report
553 * "no such column" (we already determined there wasn't one). If
554 * dealing with function notation, report "ambiguous function",
555 * regardless of whether there's also a column by this name.
556 */
557 if (is_column)
558 return NULL;
559
560 if (proc_call)
562 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
563 errmsg("procedure %s is not unique",
564 func_signature_string(funcname, nargs, argnames,
565 actual_arg_types)),
566 errhint("Could not choose a best candidate procedure. "
567 "You might need to add explicit type casts."),
568 parser_errposition(pstate, location)));
569 else
571 (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
572 errmsg("function %s is not unique",
573 func_signature_string(funcname, nargs, argnames,
574 actual_arg_types)),
575 errhint("Could not choose a best candidate function. "
576 "You might need to add explicit type casts."),
577 parser_errposition(pstate, location)));
578 }
579 else
580 {
581 /*
582 * Not found as a function. If we are dealing with attribute
583 * notation, return failure, letting the caller report "no such
584 * column" (we already determined there wasn't one).
585 */
586 if (is_column)
587 return NULL;
588
589 /*
590 * Check for column projection interpretation, since we didn't before.
591 */
592 if (could_be_projection)
593 {
594 retval = ParseComplexProjection(pstate,
596 first_arg,
597 location);
598 if (retval)
599 return retval;
600 }
601
602 /*
603 * No function, and no column either. Since we're dealing with
604 * function notation, report "function does not exist".
605 */
606 if (list_length(agg_order) > 1 && !agg_within_group)
607 {
608 /* It's agg(x, ORDER BY y,z) ... perhaps misplaced ORDER BY */
610 (errcode(ERRCODE_UNDEFINED_FUNCTION),
611 errmsg("function %s does not exist",
612 func_signature_string(funcname, nargs, argnames,
613 actual_arg_types)),
614 errhint("No aggregate function matches the given name and argument types. "
615 "Perhaps you misplaced ORDER BY; ORDER BY must appear "
616 "after all regular arguments of the aggregate."),
617 parser_errposition(pstate, location)));
618 }
619 else if (proc_call)
621 (errcode(ERRCODE_UNDEFINED_FUNCTION),
622 errmsg("procedure %s does not exist",
623 func_signature_string(funcname, nargs, argnames,
624 actual_arg_types)),
625 errhint("No procedure matches the given name and argument types. "
626 "You might need to add explicit type casts."),
627 parser_errposition(pstate, location)));
628 else
630 (errcode(ERRCODE_UNDEFINED_FUNCTION),
631 errmsg("function %s does not exist",
632 func_signature_string(funcname, nargs, argnames,
633 actual_arg_types)),
634 errhint("No function matches the given name and argument types. "
635 "You might need to add explicit type casts."),
636 parser_errposition(pstate, location)));
637 }
638
639 /*
640 * If there are default arguments, we have to include their types in
641 * actual_arg_types for the purpose of checking generic type consistency.
642 * However, we do NOT put them into the generated parse node, because
643 * their actual values might change before the query gets run. The
644 * planner has to insert the up-to-date values at plan time.
645 */
646 nargsplusdefs = nargs;
647 foreach(l, argdefaults)
648 {
649 Node *expr = (Node *) lfirst(l);
650
651 /* probably shouldn't happen ... */
652 if (nargsplusdefs >= FUNC_MAX_ARGS)
654 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
655 errmsg_plural("cannot pass more than %d argument to a function",
656 "cannot pass more than %d arguments to a function",
659 parser_errposition(pstate, location)));
660
661 actual_arg_types[nargsplusdefs++] = exprType(expr);
662 }
663
664 /*
665 * enforce consistency with polymorphic argument and return types,
666 * possibly adjusting return type or declared_arg_types (which will be
667 * used as the cast destination by make_fn_arguments)
668 */
669 rettype = enforce_generic_type_consistency(actual_arg_types,
670 declared_arg_types,
671 nargsplusdefs,
672 rettype,
673 false);
674
675 /* perform the necessary typecasting of arguments */
676 make_fn_arguments(pstate, fargs, actual_arg_types, declared_arg_types);
677
678 /*
679 * If the function isn't actually variadic, forget any VARIADIC decoration
680 * on the call. (Perhaps we should throw an error instead, but
681 * historically we've allowed people to write that.)
682 */
683 if (!OidIsValid(vatype))
684 {
685 Assert(nvargs == 0);
686 func_variadic = false;
687 }
688
689 /*
690 * If it's a variadic function call, transform the last nvargs arguments
691 * into an array --- unless it's an "any" variadic.
692 */
693 if (nvargs > 0 && vatype != ANYOID)
694 {
696 int non_var_args = nargs - nvargs;
697 List *vargs;
698
699 Assert(non_var_args >= 0);
700 vargs = list_copy_tail(fargs, non_var_args);
701 fargs = list_truncate(fargs, non_var_args);
702
703 newa->elements = vargs;
704 /* assume all the variadic arguments were coerced to the same type */
705 newa->element_typeid = exprType((Node *) linitial(vargs));
706 newa->array_typeid = get_array_type(newa->element_typeid);
707 if (!OidIsValid(newa->array_typeid))
709 (errcode(ERRCODE_UNDEFINED_OBJECT),
710 errmsg("could not find array type for data type %s",
711 format_type_be(newa->element_typeid)),
712 parser_errposition(pstate, exprLocation((Node *) vargs))));
713 /* array_collid will be set by parse_collate.c */
714 newa->multidims = false;
715 newa->location = exprLocation((Node *) vargs);
716
717 fargs = lappend(fargs, newa);
718
719 /* We could not have had VARIADIC marking before ... */
720 Assert(!func_variadic);
721 /* ... but now, it's a VARIADIC call */
722 func_variadic = true;
723 }
724
725 /*
726 * If an "any" variadic is called with explicit VARIADIC marking, insist
727 * that the variadic parameter be of some array type.
728 */
729 if (nargs > 0 && vatype == ANYOID && func_variadic)
730 {
731 Oid va_arr_typid = actual_arg_types[nargs - 1];
732
733 if (!OidIsValid(get_base_element_type(va_arr_typid)))
735 (errcode(ERRCODE_DATATYPE_MISMATCH),
736 errmsg("VARIADIC argument must be an array"),
737 parser_errposition(pstate,
738 exprLocation((Node *) llast(fargs)))));
739 }
740
741 /* if it returns a set, check that's OK */
742 if (retset)
743 check_srf_call_placement(pstate, last_srf, location);
744
745 /* build the appropriate output structure */
746 if (fdresult == FUNCDETAIL_NORMAL || fdresult == FUNCDETAIL_PROCEDURE)
747 {
748 FuncExpr *funcexpr = makeNode(FuncExpr);
749
750 funcexpr->funcid = funcid;
751 funcexpr->funcresulttype = rettype;
752 funcexpr->funcretset = retset;
753 funcexpr->funcvariadic = func_variadic;
754 funcexpr->funcformat = funcformat;
755 /* funccollid and inputcollid will be set by parse_collate.c */
756 funcexpr->args = fargs;
757 funcexpr->location = location;
758
759 retval = (Node *) funcexpr;
760 }
761 else if (fdresult == FUNCDETAIL_AGGREGATE && !over)
762 {
763 /* aggregate function */
764 Aggref *aggref = makeNode(Aggref);
765
766 aggref->aggfnoid = funcid;
767 aggref->aggtype = rettype;
768 /* aggcollid and inputcollid will be set by parse_collate.c */
769 aggref->aggtranstype = InvalidOid; /* will be set by planner */
770 /* aggargtypes will be set by transformAggregateCall */
771 /* aggdirectargs and args will be set by transformAggregateCall */
772 /* aggorder and aggdistinct will be set by transformAggregateCall */
773 aggref->aggfilter = agg_filter;
774 aggref->aggstar = agg_star;
775 aggref->aggvariadic = func_variadic;
776 aggref->aggkind = aggkind;
777 aggref->aggpresorted = false;
778 /* agglevelsup will be set by transformAggregateCall */
779 aggref->aggsplit = AGGSPLIT_SIMPLE; /* planner might change this */
780 aggref->aggno = -1; /* planner will set aggno and aggtransno */
781 aggref->aggtransno = -1;
782 aggref->location = location;
783
784 /*
785 * Reject attempt to call a parameterless aggregate without (*)
786 * syntax. This is mere pedantry but some folks insisted ...
787 */
788 if (fargs == NIL && !agg_star && !agg_within_group)
790 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
791 errmsg("%s(*) must be used to call a parameterless aggregate function",
793 parser_errposition(pstate, location)));
794
795 if (retset)
797 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
798 errmsg("aggregates cannot return sets"),
799 parser_errposition(pstate, location)));
800
801 /*
802 * We might want to support named arguments later, but disallow it for
803 * now. We'd need to figure out the parsed representation (should the
804 * NamedArgExprs go above or below the TargetEntry nodes?) and then
805 * teach the planner to reorder the list properly. Or maybe we could
806 * make transformAggregateCall do that? However, if you'd also like
807 * to allow default arguments for aggregates, we'd need to do it in
808 * planning to avoid semantic problems.
809 */
810 if (argnames != NIL)
812 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
813 errmsg("aggregates cannot use named arguments"),
814 parser_errposition(pstate, location)));
815
816 /* parse_agg.c does additional aggregate-specific processing */
817 transformAggregateCall(pstate, aggref, fargs, agg_order, agg_distinct);
818
819 retval = (Node *) aggref;
820 }
821 else
822 {
823 /* window function */
825
826 Assert(over); /* lack of this was checked above */
827 Assert(!agg_within_group); /* also checked above */
828
829 wfunc->winfnoid = funcid;
830 wfunc->wintype = rettype;
831 /* wincollid and inputcollid will be set by parse_collate.c */
832 wfunc->args = fargs;
833 /* winref will be set by transformWindowFuncCall */
834 wfunc->winstar = agg_star;
835 wfunc->winagg = (fdresult == FUNCDETAIL_AGGREGATE);
836 wfunc->aggfilter = agg_filter;
837 wfunc->runCondition = NIL;
838 wfunc->location = location;
839
840 /*
841 * agg_star is allowed for aggregate functions but distinct isn't
842 */
843 if (agg_distinct)
845 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
846 errmsg("DISTINCT is not implemented for window functions"),
847 parser_errposition(pstate, location)));
848
849 /*
850 * Reject attempt to call a parameterless aggregate without (*)
851 * syntax. This is mere pedantry but some folks insisted ...
852 */
853 if (wfunc->winagg && fargs == NIL && !agg_star)
855 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
856 errmsg("%s(*) must be used to call a parameterless aggregate function",
858 parser_errposition(pstate, location)));
859
860 /*
861 * ordered aggs not allowed in windows yet
862 */
863 if (agg_order != NIL)
865 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
866 errmsg("aggregate ORDER BY is not implemented for window functions"),
867 parser_errposition(pstate, location)));
868
869 /*
870 * FILTER is not yet supported with true window functions
871 */
872 if (!wfunc->winagg && agg_filter)
874 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
875 errmsg("FILTER is not implemented for non-aggregate window functions"),
876 parser_errposition(pstate, location)));
877
878 /*
879 * Window functions can't either take or return sets
880 */
881 if (pstate->p_last_srf != last_srf)
883 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
884 errmsg("window function calls cannot contain set-returning function calls"),
885 errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
886 parser_errposition(pstate,
887 exprLocation(pstate->p_last_srf))));
888
889 if (retset)
891 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
892 errmsg("window functions cannot return sets"),
893 parser_errposition(pstate, location)));
894
895 /* parse_agg.c does additional window-func-specific processing */
896 transformWindowFuncCall(pstate, wfunc, over);
897
898 retval = (Node *) wfunc;
899 }
900
901 /* if it returns a set, remember it for error checks at higher levels */
902 if (retset)
903 pstate->p_last_srf = retval;
904
905 return retval;
906}
int errhint_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1339
List * list_copy_tail(const List *oldlist, int nskip)
Definition: list.c:1613
List * list_truncate(List *list, int new_size)
Definition: list.c:631
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2859
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2814
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
@ AGGSPLIT_SIMPLE
Definition: nodes.h:377
void transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, WindowDef *windef)
Definition: parse_agg.c:825
void transformAggregateCall(ParseState *pstate, Aggref *agg, List *args, List *aggorder, bool agg_distinct)
Definition: parse_agg.c:109
Node * transformWhereClause(ParseState *pstate, Node *clause, ParseExprKind exprKind, const char *constructName)
Oid enforce_generic_type_consistency(const Oid *actual_arg_types, Oid *declared_arg_types, int nargs, Oid rettype, bool allow_poly)
static Node * ParseComplexProjection(ParseState *pstate, const char *funcname, Node *first_arg, int location)
Definition: parse_func.c:1912
void make_fn_arguments(ParseState *pstate, List *fargs, Oid *actual_arg_types, Oid *declared_arg_types)
Definition: parse_func.c:1825
static void unify_hypothetical_args(ParseState *pstate, List *fargs, int numAggregatedArgs, Oid *actual_arg_types, Oid *declared_arg_types)
Definition: parse_func.c:1741
FuncDetailCode func_get_detail(List *funcname, List *fargs, List *fargnames, int nargs, Oid *argtypes, bool expand_variadic, bool expand_defaults, bool include_out_arguments, Oid *funcid, Oid *rettype, bool *retset, int *nvargs, Oid *vatype, Oid **true_typeids, List **argdefaults)
Definition: parse_func.c:1395
void check_srf_call_placement(ParseState *pstate, Node *last_srf, int location)
Definition: parse_func.c:2511
void cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
Definition: parse_node.c:156
void setup_parser_errposition_callback(ParseCallbackState *pcbstate, ParseState *pstate, int location)
Definition: parse_node.c:140
FormData_pg_aggregate * Form_pg_aggregate
Definition: pg_aggregate.h:109
void * arg
#define llast(l)
Definition: pg_list.h:198
#define foreach_delete_current(lst, var_or_cell)
Definition: pg_list.h:391
int16 pronargs
Definition: pg_proc.h:81
CoercionForm
Definition: primnodes.h:750
@ COERCE_EXPLICIT_CALL
Definition: primnodes.h:751
Oid aggfnoid
Definition: primnodes.h:461
Expr * aggfilter
Definition: primnodes.h:494
ParseLoc location
Definition: primnodes.h:524
ParseLoc location
Definition: primnodes.h:1401
List * elements
Definition: primnodes.h:1397
ParseLoc location
Definition: primnodes.h:787
Oid funcid
Definition: primnodes.h:767
List * args
Definition: primnodes.h:785
ParseLoc location
Definition: primnodes.h:814
List * args
Definition: primnodes.h:592
Expr * aggfilter
Definition: primnodes.h:594
ParseLoc location
Definition: primnodes.h:604
Oid winfnoid
Definition: primnodes.h:584
static void * fn(void *arg)
Definition: thread-alloc.c:119
#define strVal(v)
Definition: value.h:82

References Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggfnoid, AGGSPLIT_SIMPLE, arg, WindowFunc::args, FuncExpr::args, Assert, cancel_parser_errposition_callback(), check_srf_call_placement(), COERCE_EXPLICIT_CALL, coerce_type(), COERCION_EXPLICIT, ArrayExpr::elements, elog, enforce_generic_type_consistency(), ereport, errcode(), errhint(), errhint_plural(), errmsg(), errmsg_plural(), ERROR, EXPR_KIND_FILTER, exprLocation(), exprType(), fn(), foreach_delete_current, format_type_be(), func_get_detail(), FUNC_MAX_ARGS, func_signature_string(), FUNCDETAIL_AGGREGATE, FUNCDETAIL_COERCION, FUNCDETAIL_MULTIPLE, FUNCDETAIL_NORMAL, FUNCDETAIL_PROCEDURE, FUNCDETAIL_WINDOWFUNC, FuncExpr::funcid, funcname, get_array_type(), get_base_element_type(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, IsA, ISCOMPLEX, lappend(), lfirst, linitial, list_copy_tail(), list_length(), list_truncate(), llast, Aggref::location, WindowFunc::location, FuncExpr::location, NamedArgExpr::location, ArrayExpr::location, make_fn_arguments(), makeNode, NameListToString(), NIL, ObjectIdGetDatum(), OidIsValid, ParseState::p_last_srf, ParseComplexProjection(), parser_errposition(), pronargs, ReleaseSysCache(), SearchSysCache1(), setup_parser_errposition_callback(), strVal, transformAggregateCall(), transformWhereClause(), transformWindowFuncCall(), unify_hypothetical_args(), and WindowFunc::winfnoid.

Referenced by sql_fn_post_column_ref(), transformCallStmt(), transformColumnRef(), transformFuncCall(), and transformIndirection().

◆ unify_hypothetical_args()

static void unify_hypothetical_args ( ParseState pstate,
List fargs,
int  numAggregatedArgs,
Oid actual_arg_types,
Oid declared_arg_types 
)
static

Definition at line 1741 of file parse_func.c.

1746{
1747 int numDirectArgs,
1748 numNonHypotheticalArgs;
1749 int hargpos;
1750
1751 numDirectArgs = list_length(fargs) - numAggregatedArgs;
1752 numNonHypotheticalArgs = numDirectArgs - numAggregatedArgs;
1753 /* safety check (should only trigger with a misdeclared agg) */
1754 if (numNonHypotheticalArgs < 0)
1755 elog(ERROR, "incorrect number of arguments to hypothetical-set aggregate");
1756
1757 /* Check each hypothetical arg and corresponding aggregated arg */
1758 for (hargpos = numNonHypotheticalArgs; hargpos < numDirectArgs; hargpos++)
1759 {
1760 int aargpos = numDirectArgs + (hargpos - numNonHypotheticalArgs);
1761 ListCell *harg = list_nth_cell(fargs, hargpos);
1762 ListCell *aarg = list_nth_cell(fargs, aargpos);
1763 Oid commontype;
1764 int32 commontypmod;
1765
1766 /* A mismatch means AggregateCreate didn't check properly ... */
1767 if (declared_arg_types[hargpos] != declared_arg_types[aargpos])
1768 elog(ERROR, "hypothetical-set aggregate has inconsistent declared argument types");
1769
1770 /* No need to unify if make_fn_arguments will coerce */
1771 if (declared_arg_types[hargpos] != ANYOID)
1772 continue;
1773
1774 /*
1775 * Select common type, giving preference to the aggregated argument's
1776 * type (we'd rather coerce the direct argument once than coerce all
1777 * the aggregated values).
1778 */
1779 commontype = select_common_type(pstate,
1780 list_make2(lfirst(aarg), lfirst(harg)),
1781 "WITHIN GROUP",
1782 NULL);
1783 commontypmod = select_common_typmod(pstate,
1784 list_make2(lfirst(aarg), lfirst(harg)),
1785 commontype);
1786
1787 /*
1788 * Perform the coercions. We don't need to worry about NamedArgExprs
1789 * here because they aren't supported with aggregates.
1790 */
1791 lfirst(harg) = coerce_type(pstate,
1792 (Node *) lfirst(harg),
1793 actual_arg_types[hargpos],
1794 commontype, commontypmod,
1797 -1);
1798 actual_arg_types[hargpos] = commontype;
1799 lfirst(aarg) = coerce_type(pstate,
1800 (Node *) lfirst(aarg),
1801 actual_arg_types[aargpos],
1802 commontype, commontypmod,
1805 -1);
1806 actual_arg_types[aargpos] = commontype;
1807 }
1808}
int32_t int32
Definition: c.h:484
int32 select_common_typmod(ParseState *pstate, List *exprs, Oid common_type)
Oid select_common_type(ParseState *pstate, List *exprs, const char *context, Node **which_expr)
static ListCell * list_nth_cell(const List *list, int n)
Definition: pg_list.h:277
#define list_make2(x1, x2)
Definition: pg_list.h:214

References COERCE_IMPLICIT_CAST, coerce_type(), COERCION_IMPLICIT, elog, ERROR, lfirst, list_length(), list_make2, list_nth_cell(), select_common_type(), and select_common_typmod().

Referenced by ParseFuncOrColumn().