diff options
Diffstat (limited to 'src/backend/parser')
-rw-r--r-- | src/backend/parser/analyze.c | 4 | ||||
-rw-r--r-- | src/backend/parser/parse_expr.c | 14 | ||||
-rw-r--r-- | src/backend/parser/parse_func.c | 226 | ||||
-rw-r--r-- | src/backend/parser/parse_node.c | 6 | ||||
-rw-r--r-- | src/backend/parser/parse_relation.c | 4 | ||||
-rw-r--r-- | src/backend/parser/parse_target.c | 4 |
6 files changed, 79 insertions, 179 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 5824c300d7c..09f90fe3bc3 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: analyze.c,v 1.152 2000/08/03 16:35:08 tgl Exp $ + * $Id: analyze.c,v 1.153 2000/08/08 15:42:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -470,7 +470,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) thisatt->atttypid, thisatt->atttypmod, pstrdup(NameStr(thisatt->attname)), - 0, 0, false), + false), stringToNode(defval[ndef].adbin)); qry->targetList = lappend(qry->targetList, te); diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 8c3e64d6d86..7976f5e7795 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.81 2000/06/15 03:32:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.82 2000/08/08 15:42:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -133,7 +133,6 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) param->paramid = (AttrNumber) paramno; param->paramname = "<unnamed>"; param->paramtype = toid; - param->param_tlist = NIL; result = transformIndirection(pstate, (Node *) param, pno->indirection); /* cope with typecast applied to param */ @@ -381,9 +380,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) newop = makeOper(oprid(optup), /* opno */ InvalidOid, /* opid */ - opform->oprresult, - 0, - NULL); + opform->oprresult); sublink->oper = lappend(sublink->oper, newop); } if (left_list != NIL) @@ -579,6 +576,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) case T_Param: case T_Aggref: case T_ArrayRef: + case T_FieldSelect: case T_RelabelType: { result = (Node *) expr; @@ -690,6 +688,9 @@ exprType(Node *expr) case T_Param: type = ((Param *) expr)->paramtype; break; + case T_FieldSelect: + type = ((FieldSelect *) expr)->resulttype; + break; case T_RelabelType: type = ((RelabelType *) expr)->resulttype; break; @@ -773,6 +774,9 @@ exprTypmod(Node *expr) return coercedTypmod; } break; + case T_FieldSelect: + return ((FieldSelect *) expr)->resulttypmod; + break; case T_RelabelType: return ((RelabelType *) expr)->resulttypmod; break; diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index d1a5e44f873..44a750c166e 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.86 2000/08/03 19:19:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.87 2000/08/08 15:42:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -59,7 +59,7 @@ static int match_argtypes(int nargs, Oid *input_typeids, CandidateList function_typeids, CandidateList *candidates); -static List *setup_tlist(char *attname, Oid relid); +static FieldSelect *setup_field_select(Node *input, char *attname, Oid relid); static Oid *func_select_candidate(int nargs, Oid *input_typeids, CandidateList candidates); static int agg_get_candidates(char *aggname, Oid typeId, CandidateList *candidates); @@ -394,10 +394,9 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, argrelid = typeidTypeRelid(toid); /* - * A projection contains either an attribute name or "*". + * A projection must match an attribute name of the rel. */ - if ((get_attnum(argrelid, funcname) == InvalidAttrNumber) - && strcmp(funcname, "*")) + if (get_attnum(argrelid, funcname) == InvalidAttrNumber) elog(ERROR, "Functions on sets are not yet supported"); } @@ -670,43 +669,12 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, funcnode = makeNode(Func); funcnode->funcid = funcid; funcnode->functype = rettype; - funcnode->funcisindex = false; - funcnode->funcsize = 0; funcnode->func_fcache = NULL; - funcnode->func_tlist = NIL; - funcnode->func_planlist = NIL; - /* perform the necessary typecasting */ + /* perform the necessary typecasting of arguments */ make_arguments(pstate, nargs, fargs, oid_array, true_oid_array); /* - * for functions returning base types, we want to project out the - * return value. set up a target list to do that. the executor will - * ignore these for c functions, and do the right thing for postquel - * functions. - */ - - if (typeidTypeRelid(rettype) == InvalidOid) - funcnode->func_tlist = setup_base_tlist(rettype); - - /* - * For sets, we want to make a targetlist to project out this - * attribute of the set tuples. - */ - if (attisset) - { - if (!strcmp(funcname, "*")) - funcnode->func_tlist = expandAll(pstate, relname, - makeAttr(refname, NULL), - curr_resno); - else - { - funcnode->func_tlist = setup_tlist(funcname, argrelid); - rettype = get_atttype(argrelid, get_attnum(argrelid, funcname)); - } - } - - /* * Special checks to disallow sequence functions with side-effects * in WHERE clauses. This is pretty much of a hack; why disallow these * when we have no way to check for side-effects of user-defined fns? @@ -724,6 +692,18 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, retval = (Node *) expr; /* + * For sets, we want to project out the desired attribute of the tuples. + */ + if (attisset) + { + FieldSelect *fselect; + + fselect = setup_field_select(retval, funcname, argrelid); + rettype = fselect->resulttype; + retval = (Node *) fselect; + } + + /* * if the function returns a set of values, then we need to iterate * over all the returned values in the executor, so we stick an iter * node here. if it returns a singleton, then we don't need the iter @@ -1524,66 +1504,30 @@ make_arguments(ParseState *pstate, } /* - ** setup_tlist - ** Build a tlist that says which attribute to project to. - ** This routine is called by ParseFuncOrColumn() to set up a target list - ** on a tuple parameter or return value. Due to a bug in 4.0, - ** it's not possible to refer to system attributes in this case. + ** setup_field_select + ** Build a FieldSelect node that says which attribute to project to. + ** This routine is called by ParseFuncOrColumn() when we have found + ** a projection on a function result or parameter. */ -static List * -setup_tlist(char *attname, Oid relid) +static FieldSelect * +setup_field_select(Node *input, char *attname, Oid relid) { - TargetEntry *tle; - Resdom *resnode; - Var *varnode; - Oid typeid; - int32 type_mod; - int attno; + FieldSelect *fselect = makeNode(FieldSelect); + AttrNumber attno; attno = get_attnum(relid, attname); + + /* XXX Is there still a reason for this restriction? */ if (attno < 0) elog(ERROR, "Cannot reference attribute '%s'" " of tuple params/return values for functions", attname); - typeid = get_atttype(relid, attno); - type_mod = get_atttypmod(relid, attno); - - resnode = makeResdom(1, - typeid, - type_mod, - get_attname(relid, attno), - 0, - InvalidOid, - false); - varnode = makeVar(-1, attno, typeid, type_mod, 0); + fselect->arg = input; + fselect->fieldnum = attno; + fselect->resulttype = get_atttype(relid, attno); + fselect->resulttypmod = get_atttypmod(relid, attno); - tle = makeTargetEntry(resnode, (Node *) varnode); - return lcons(tle, NIL); -} - -/* - ** setup_base_tlist - ** Build a tlist that extracts a base type from the tuple - ** returned by the executor. - */ -List * -setup_base_tlist(Oid typeid) -{ - TargetEntry *tle; - Resdom *resnode; - Var *varnode; - - resnode = makeResdom(1, - typeid, - -1, - "<noname>", - 0, - InvalidOid, - false); - varnode = makeVar(-1, 1, typeid, -1, 0); - tle = makeTargetEntry(resnode, (Node *) varnode); - - return lcons(tle, NIL); + return fselect; } /* @@ -1599,51 +1543,32 @@ ParseComplexProjection(ParseState *pstate, { Oid argtype; Oid argrelid; - Relation rd; - Oid relid; - int attnum; + FieldSelect *fselect; switch (nodeTag(first_arg)) { case T_Iter: { - Func *func; - Iter *iter; + Iter *iter = (Iter *) first_arg; - iter = (Iter *) first_arg; - func = (Func *) ((Expr *) iter->iterexpr)->oper; - argtype = get_func_rettype(func->funcid); + /* + * If the argument of the Iter returns a tuple, + * funcname may be a projection. If so, we stick + * the FieldSelect *inside* the Iter --- this is + * klugy, but necessary because ExecTargetList() + * currently does the right thing only when the + * Iter node is at the top level of a targetlist item. + */ + argtype = iter->itertype; argrelid = typeidTypeRelid(argtype); if (argrelid && - ((attnum = get_attnum(argrelid, funcname)) - != InvalidAttrNumber)) + get_attnum(argrelid, funcname) != InvalidAttrNumber) { - - /* - * the argument is a function returning a tuple, so - * funcname may be a projection - */ - - /* add a tlist to the func node and return the Iter */ - rd = heap_openr_nofail(typeidTypeName(argtype)); - if (RelationIsValid(rd)) - { - relid = RelationGetRelid(rd); - func->func_tlist = setup_tlist(funcname, argrelid); - iter->itertype = attnumTypeId(rd, attnum); - heap_close(rd, NoLock); - return (Node *) iter; - } - else - { - elog(ERROR, "Function '%s' has bad return type %d", - funcname, argtype); - } - } - else - { - /* drop through */ - ; + fselect = setup_field_select(iter->iterexpr, + funcname, argrelid); + iter->iterexpr = (Node *) fselect; + iter->itertype = fselect->resulttype; + return (Node *) iter; } break; } @@ -1665,38 +1590,20 @@ ParseComplexProjection(ParseState *pstate, if (expr->opType != FUNC_EXPR) break; - funcnode = (Func *) expr->oper; - argtype = get_func_rettype(funcnode->funcid); - argrelid = typeidTypeRelid(argtype); - /* - * the argument is a function returning a tuple, so + * If the argument is a function returning a tuple, * funcname may be a projection */ + funcnode = (Func *) expr->oper; + argtype = funcnode->functype; + argrelid = typeidTypeRelid(argtype); if (argrelid && - (attnum = get_attnum(argrelid, funcname)) - != InvalidAttrNumber) + get_attnum(argrelid, funcname) != InvalidAttrNumber) { - Expr *newexpr; - - /* add a tlist to the func node */ - rd = heap_openr(typeidTypeName(argtype), NoLock); - - relid = RelationGetRelid(rd); - funcnode->func_tlist = setup_tlist(funcname, argrelid); - funcnode->functype = attnumTypeId(rd, attnum); - - newexpr = makeNode(Expr); - newexpr->typeOid = funcnode->functype; - newexpr->opType = FUNC_EXPR; - newexpr->oper = (Node *) funcnode; - newexpr->args = expr->args; - - heap_close(rd, NoLock); - - return (Node *) newexpr; + fselect = setup_field_select((Node *) expr, + funcname, argrelid); + return (Node *) fselect; } - break; } case T_Param: @@ -1707,19 +1614,14 @@ ParseComplexProjection(ParseState *pstate, * If the Param is a complex type, this could be a * projection */ - rd = heap_openr_nofail(typeidTypeName(param->paramtype)); - if (RelationIsValid(rd)) + argtype = param->paramtype; + argrelid = typeidTypeRelid(argtype); + if (argrelid && + get_attnum(argrelid, funcname) != InvalidAttrNumber) { - relid = RelationGetRelid(rd); - if ((attnum = get_attnum(relid, funcname)) - != InvalidAttrNumber) - { - param->paramtype = attnumTypeId(rd, attnum); - param->param_tlist = setup_tlist(funcname, relid); - heap_close(rd, NoLock); - return (Node *) param; - } - heap_close(rd, NoLock); + fselect = setup_field_select((Node *) param, + funcname, argrelid); + return (Node *) fselect; } break; } diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c index 273dc0ef644..2bda101538c 100644 --- a/src/backend/parser/parse_node.c +++ b/src/backend/parser/parse_node.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.43 2000/07/05 23:11:32 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.44 2000/08/08 15:42:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -161,9 +161,7 @@ make_op(char *opname, Node *ltree, Node *rtree) newop = makeOper(oprid(tup),/* opno */ InvalidOid,/* opid */ - opform->oprresult, /* operator result type */ - 0, - NULL); + opform->oprresult); /* operator result type */ result = makeNode(Expr); result->typeOid = opform->oprresult; diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 7a3e3c2d6ad..802299c8966 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.45 2000/07/02 22:00:41 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.46 2000/08/08 15:42:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -412,8 +412,6 @@ expandAll(ParseState *pstate, char *relname, Attr *ref, int *this_resno) varnode->vartype, varnode->vartypmod, label, - (Index) 0, - (Oid) 0, false); te->expr = (Node *) varnode; te_list = lappend(te_list, te); diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 2f076028cc9..1564f976b04 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.60 2000/06/15 03:32:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.61 2000/08/08 15:42:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -71,8 +71,6 @@ transformTargetEntry(ParseState *pstate, type_id, type_mod, colname, - (Index) 0, - (Oid) InvalidOid, resjunk); return makeTargetEntry(resnode, expr); |