diff options
Diffstat (limited to 'src/backend/parser/parse_func.c')
-rw-r--r-- | src/backend/parser/parse_func.c | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 07d52ef5441..64a325f10b7 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.176 2005/03/29 03:01:31 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.177 2005/03/31 22:46:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,6 +18,7 @@ #include "catalog/catname.h" #include "catalog/pg_inherits.h" #include "catalog/pg_proc.h" +#include "funcapi.h" #include "lib/stringinfo.h" #include "nodes/makefuncs.h" #include "parser/parse_agg.h" @@ -1154,10 +1155,8 @@ make_fn_arguments(ParseState *pstate, static Node * ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg) { - Oid argtype; - Oid argrelid; - AttrNumber attnum; - FieldSelect *fselect; + TupleDesc tupdesc; + int i; /* * Special case for whole-row Vars so that we can resolve (foo.*).bar @@ -1180,27 +1179,31 @@ ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg) /* * Else do it the hard way. Note that if the arg is of RECORD type, - * we will never recognize a column name, and always assume the item - * must be a function. + * and isn't resolvable as a function with OUT params, we will never + * be able to recognize a column name here. */ - argtype = exprType(first_arg); - argrelid = typeidTypeRelid(argtype); - if (!argrelid) - return NULL; /* can only happen if RECORD */ - - attnum = get_attnum(argrelid, funcname); - if (attnum == InvalidAttrNumber) - return NULL; /* funcname does not match any column */ - - /* Success, so generate a FieldSelect expression */ - fselect = makeNode(FieldSelect); - fselect->arg = (Expr *) first_arg; - fselect->fieldnum = attnum; - get_atttypetypmod(argrelid, attnum, - &fselect->resulttype, - &fselect->resulttypmod); - - return (Node *) fselect; + if (get_expr_result_type(first_arg, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + return NULL; /* unresolvable RECORD type */ + + for (i = 0; i < tupdesc->natts; i++) + { + Form_pg_attribute att = tupdesc->attrs[i]; + + if (strcmp(funcname, NameStr(att->attname)) == 0 && + !att->attisdropped) + { + /* Success, so generate a FieldSelect expression */ + FieldSelect *fselect = makeNode(FieldSelect); + + fselect->arg = (Expr *) first_arg; + fselect->fieldnum = i + 1; + fselect->resulttype = att->atttypid; + fselect->resulttypmod = att->atttypmod; + return (Node *) fselect; + } + } + + return NULL; /* funcname does not match any column */ } /* |