aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_func.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_func.c')
-rw-r--r--src/backend/parser/parse_func.c53
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 */
}
/*