diff --git a/src/backend/commands/recipe.c b/src/backend/commands/recipe.c index bfdfe9d78f..96808a6e31 100644 --- a/src/backend/commands/recipe.c +++ b/src/backend/commands/recipe.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/recipe.c,v 1.17 1998/01/05 16:38:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/recipe.c,v 1.18 1998/01/20 22:10:53 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -494,6 +494,7 @@ tg_replaceNumberedParam(Node *expression, newVar = makeVar(rt_ind, 0, /* the whole tuple */ TypeGet(teeRelName, &defined), + 0, rt_ind, 0); return (Node *) newVar; @@ -503,6 +504,7 @@ tg_replaceNumberedParam(Node *expression, 1, /* just the first field, * which is 'result' */ TypeGet(teeRelName, &defined), + 0, rt_ind, 0); return (Node *) newVar; diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index d6cc4cd547..c3b98a555f 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.34 1998/01/20 05:03:40 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.35 1998/01/20 22:10:58 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -671,6 +671,7 @@ _copyVar(Var *from) newnode->varno = from->varno; newnode->varattno = from->varattno; newnode->vartype = from->vartype; + newnode->varlevelsup = from->varlevelsup; newnode->varnoold = from->varnoold; newnode->varoattno = from->varoattno; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index d569bd4712..bfed02b5e5 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.12 1998/01/07 21:03:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.13 1998/01/20 22:11:02 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -129,6 +129,8 @@ _equalVar(Var *a, Var *b) return (false); if (a->vartype != b->vartype) return (false); + if (a->varlevelsup != b->varlevelsup) + return (false); if (a->varnoold != b->varnoold) return (false); if (a->varoattno != b->varoattno) diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index 95cce161d6..af5003e877 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.4 1997/09/08 02:23:39 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.5 1998/01/20 22:11:05 momjian Exp $ * * NOTES * Creator functions in POSTGRES 4.2 are generated automatically. Most of @@ -53,6 +53,7 @@ Var * makeVar(Index varno, AttrNumber varattno, Oid vartype, + Index varlevelsup, Index varnoold, AttrNumber varoattno) { @@ -61,6 +62,7 @@ makeVar(Index varno, var->varno = varno; var->varattno = varattno; var->vartype = vartype; + var->varlevelsup = varlevelsup; var->varnoold = varnoold; var->varoattno = varoattno; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index d7ede89e65..6f69c34983 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.25 1998/01/20 05:03:49 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.26 1998/01/20 22:11:12 momjian Exp $ * * NOTES * Every (plan) node in POSTGRES has an associated "out" routine which @@ -698,6 +698,8 @@ _outVar(StringInfo str, Var *node) appendStringInfo(str, buf); sprintf(buf, " :vartype %u ", node->vartype); appendStringInfo(str, buf); + sprintf(buf, " :varlevelsup %u ", node->varlevelsup); + appendStringInfo(str, buf); sprintf(buf, " :varnoold %d ", node->varnoold); appendStringInfo(str, buf); sprintf(buf, " :varoattno %d ", node->varoattno); diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 2860bad174..d0bcf13875 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.21 1998/01/20 05:03:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.22 1998/01/20 22:11:15 momjian Exp $ * * NOTES * Most of the read functions for plan nodes are tested. (In fact, they @@ -814,6 +814,10 @@ _readVar() token = lsptok(NULL, &length); /* get vartype */ local_node->vartype = (Oid) atol(token); + token = lsptok(NULL, &length); /* eat :varlevelsup */ + token = lsptok(NULL, &length); /* get varlevelsup */ + local_node->varlevelsup = (Oid) atol(token); + token = lsptok(NULL, &length); /* eat :varnoold */ token = lsptok(NULL, &length); /* get varnoold */ local_node->varnoold = (Oid) atol(token); diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 970a6a5ffb..2b53f1875f 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.23 1998/01/15 18:59:37 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.24 1998/01/20 22:11:25 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -701,6 +701,7 @@ fix_indxqual_references(Node *clause, Path *index_path) makeVar((Index) lfirsti(index_path->parent->relids), 1, /* func indices have one key */ ((Func *) ((Expr *) clause)->oper)->functype, + 0, (Index) lfirsti(index_path->parent->relids), 0); diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index d7edd0aaea..cb0bd08587 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.8 1997/09/08 21:45:19 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.9 1998/01/20 22:11:27 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -116,7 +116,7 @@ add_missing_vars_to_base_rels(Query *root, List *tlist) !rel_member(relids, root->base_relation_list_)) { - var = makeVar(varno, -2, 26, varno, -2); + var = makeVar(varno, -2, 26, 0, varno, -2); /* add it to base_relation_list_ */ result = get_base_rel(root, varno); add_tl_element(result, var); diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index b8b99149ce..1c59f64a4c 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.16 1998/01/15 18:59:44 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.17 1998/01/20 22:11:29 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -464,7 +464,7 @@ make_groupPlan(List **tlist, else te->expr = (Node *) makeVar(1, resdom->resno, resdom->restype, - -1, resdom->resno); + 0, -1, resdom->resno); } sortplan = make_sort(sort_tlist, diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index fe80a658f0..284ac836f6 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.15 1998/01/15 18:59:50 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.16 1998/01/20 22:11:32 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -440,6 +440,7 @@ replace_joinvar_refs(Var *var, List *outer_tlist, List *inner_tlist) return (makeVar(OUTER, outer_resdom->resno, var->vartype, + 0, var->varnoold, var->varoattno)); } @@ -453,6 +454,7 @@ replace_joinvar_refs(Var *var, List *outer_tlist, List *inner_tlist) return (makeVar(INNER, inner_resdom->resno, var->vartype, + 0, var->varnoold, var->varoattno)); } @@ -497,6 +499,7 @@ tlist_temp_references(Oid tempid, (Node *) makeVar(tempid, xtl->resdom->resno, xtl->resdom->restype, + 0, tempid, oattno)); diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c index e92fbb3332..ad2c697db5 100644 --- a/src/backend/optimizer/prep/preptlist.c +++ b/src/backend/optimizer/prep/preptlist.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.7 1998/01/16 23:20:09 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.8 1998/01/20 22:11:34 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -114,7 +114,7 @@ preprocess_targetlist(List *tlist, 0, 1); - var = makeVar(result_relation, -1, 27, result_relation, -1); + var = makeVar(result_relation, -1, 27, 0, result_relation, -1); ctid = makeNode(TargetEntry); ctid->resdom = resdom; @@ -322,7 +322,7 @@ new_relation_targetlist(Oid relid, Index rt_index, NodeTag node_type) TargetEntry *temp_list = NULL; temp_var = - makeVar(rt_index, attno, atttype, rt_index, attno); + makeVar(rt_index, attno, atttype, 0, rt_index, attno); temp_list = MakeTLE(makeResdom(attno, atttype, diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index eab49abb1f..6f42df8ceb 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.13 1997/12/22 05:42:14 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.14 1998/01/20 22:11:39 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -377,7 +377,8 @@ clause_relids_vars(Node *clause, List **relids, List **vars) Var *in_list = (Var *) lfirst(vi); if (in_list->varno == var->varno && - in_list->varattno == var->varattno) + in_list->varattno == var->varattno && + in_list->varlevelsup == var->varlevelsup) break; } if (vi == NIL) diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c index aa867f4b5a..edac3e8bf4 100644 --- a/src/backend/optimizer/util/tlist.c +++ b/src/backend/optimizer/util/tlist.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.8 1997/11/25 22:00:16 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.9 1998/01/20 22:11:41 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -108,6 +108,7 @@ add_tl_element(Rel *rel, Var *var) Var *newvar = makeVar(var->varno, var->varattno, var->vartype, + var->varlevelsup, var->varno, var->varoattno); @@ -287,7 +288,8 @@ match_varid(Var *test_var, List *tlist) * changed to INNER/OUTER. */ if (tlvar->varnoold == test_var->varnoold && - tlvar->varoattno == test_var->varoattno) + tlvar->varoattno == test_var->varoattno && + tlvar->varlevelsup == test_var->varlevelsup) { if (tlvar->vartype == type_var) diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c index 7ba3ce5d97..e3ed305ed8 100644 --- a/src/backend/optimizer/util/var.c +++ b/src/backend/optimizer/util/var.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.7 1997/12/22 05:42:16 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.8 1998/01/20 22:11:43 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -209,6 +209,7 @@ var_equal(Var *var1, Var *var2) if (IsA(var1, Var) &&IsA(var2, Var) && (((Var *) var1)->varno == ((Var *) var2)->varno) && (((Var *) var1)->vartype == ((Var *) var2)->vartype) && + (((Var *) var1)->varlevelsup == ((Var *) var2)->varlevelsup) && (((Var *) var1)->varattno == ((Var *) var2)->varattno)) { diff --git a/src/backend/parser/README b/src/backend/parser/README index 402f193bc6..b67e1909d9 100644 --- a/src/backend/parser/README +++ b/src/backend/parser/README @@ -12,7 +12,7 @@ parse_clause.c handle clauses like WHERE, ORDER BY, GROUP BY, ... parse_expr.c handle expressions like col, col + 3, x = 3 or x = 4 parse_oper.c handle operations in expressions parse_agg.c handle aggregates, like SUM(col1), AVG(col2), ... -parse_func.c handle functions like date_part(col3), trim(col4), ... +parse_func.c handle functions, table.column and column identifiers parse_node.c create nodes for various structures parse_target.c handle the result list of the query diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 077215138f..a494106fd5 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.67 1998/01/20 05:04:05 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.68 1998/01/20 22:11:51 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -219,7 +219,7 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt) qry->qual = transformWhereClause(pstate, stmt->whereClause); qry->rtable = pstate->p_rtable; - qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname); + qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL); qry->hasAggs = pstate->p_hasAggs; if (pstate->p_hasAggs) @@ -320,7 +320,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) /* now the range table will not change */ qry->rtable = pstate->p_rtable; - qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname); + qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL); qry->groupClause = transformGroupClause(pstate, stmt->groupClause, @@ -816,7 +816,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) qry->rtable = pstate->p_rtable; - qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname); + qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL); qry->hasAggs = pstate->p_hasAggs; if (pstate->p_hasAggs) diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 115b8c153d..8e571af58f 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.10 1998/01/20 05:04:12 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.11 1998/01/20 22:11:53 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -39,16 +39,15 @@ void makeRangeTable(ParseState *pstate, char *relname, List *frmList) { RangeTblEntry *rte; - + parseFromClause(pstate, frmList); if (relname == NULL) return; - if (refnameRangeTablePosn(pstate->p_rtable, relname) < 1) - rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE); - else - rte = refnameRangeTableEntry(pstate->p_rtable, relname); + Assert(pstate->p_rtable == NULL); + + rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE); pstate->p_target_rangetblentry = rte; Assert(pstate->p_target_relation == NULL); @@ -137,8 +136,7 @@ find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist) TargetEntry *target_result = NULL; if (sortgroupby->range) - real_rtable_pos = refnameRangeTablePosn(pstate->p_rtable, - sortgroupby->range); + real_rtable_pos = refnameRangeTablePosn(pstate, sortgroupby->range, NULL); foreach(i, tlist) { diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index ef42a61fe2..485054eac1 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.11 1998/01/20 05:04:14 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.12 1998/01/20 22:11:55 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -304,6 +304,7 @@ transformIdent(ParseState *pstate, Node *expr, int precedence) { Attr *att = makeNode(Attr); + /* we add the relation name for them */ att->relname = rte->refname; att->attrs = lcons(makeString(ident->name), NIL); column_result = @@ -312,7 +313,7 @@ transformIdent(ParseState *pstate, Node *expr, int precedence) } /* try to find the ident as a relation */ - if (refnameRangeTableEntry(pstate->p_rtable, ident->name) != NULL) + if (refnameRangeTableEntry(pstate, ident->name) != NULL) { ident->isRel = TRUE; relation_result = (Node *) ident; diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index e8466fa626..d864dfc1f6 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.7 1998/01/20 05:04:16 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.8 1998/01/20 22:11:55 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -174,13 +174,12 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, { RangeTblEntry *rte; Ident *ident = (Ident *) first_arg; - /* * first arg is a relation. This could be a projection. */ refname = ident->name; - rte = refnameRangeTableEntry(pstate->p_rtable, refname); + rte = refnameRangeTableEntry(pstate, refname); if (rte == NULL) rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE); @@ -196,6 +195,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, Oid dummyTypeId; return ((Node *) make_var(pstate, + relid, refname, funcname, &dummyTypeId)); @@ -288,19 +288,18 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, if (nodeTag(pair) == T_Ident && ((Ident *) pair)->isRel) { - /* * a relation */ refname = ((Ident *) pair)->name; - rte = refnameRangeTableEntry(pstate->p_rtable, refname); + rte = refnameRangeTableEntry(pstate, refname); if (rte == NULL) rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE); relname = rte->relname; - vnum = refnameRangeTablePosn(pstate->p_rtable, rte->refname); + vnum = refnameRangeTablePosn(pstate, rte->refname, NULL); /* * for func(relname), the param to the function is the tuple @@ -312,7 +311,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, toid = typeTypeId(typenameType(relname)); /* replace it in the arg list */ lfirst(fargs) = - makeVar(vnum, 0, toid, vnum, 0); + makeVar(vnum, 0, toid, 0, vnum, 0); } else if (!attisset) { /* set functions don't have parameters */ @@ -1074,7 +1073,7 @@ setup_tlist(char *attname, Oid relid) 0, (Oid) 0, 0); - varnode = makeVar(-1, attno, typeid, -1, attno); + varnode = makeVar(-1, attno, typeid, 0, -1, attno); tle = makeNode(TargetEntry); tle->resdom = resnode; @@ -1101,7 +1100,7 @@ setup_base_tlist(Oid typeid) 0, (Oid) 0, 0); - varnode = makeVar(-1, 1, typeid, -1, 1); + varnode = makeVar(-1, 1, typeid, 0, -1, 1); tle = makeNode(TargetEntry); tle->resdom = resnode; tle->expr = (Node *) varnode; diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c index ffcafcedb1..02e5108752 100644 --- a/src/backend/parser/parse_node.c +++ b/src/backend/parser/parse_node.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.9 1998/01/20 05:04:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.10 1998/01/20 22:11:57 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -239,27 +239,24 @@ make_op(char *opname, Node *ltree, Node *rtree) } Var * -make_var(ParseState *pstate, char *refname, char *attrname, Oid *type_id) +make_var(ParseState *pstate, Oid relid, char *refname, + char *attrname, Oid *type_id) { Var *varnode; int vnum, attid; Oid vartypeid; - RangeTblEntry *rte; + int sublevels_up; - rte = refnameRangeTableEntry(pstate->p_rtable, refname); - if (rte == NULL) - rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE); + vnum = refnameRangeTablePosn(pstate, refname, &sublevels_up); - vnum = refnameRangeTablePosn(pstate->p_rtable, refname); - - attid = get_attnum(rte->relid, attrname); + attid = get_attnum(relid, attrname); if (attid == InvalidAttrNumber) elog(ERROR, "Relation %s does not have attribute %s", - rte->relname, attrname); - vartypeid = get_atttype(rte->relid, attid); + refname, attrname); + vartypeid = get_atttype(relid, attid); - varnode = makeVar(vnum, attid, vartypeid, vnum, attid); + varnode = makeVar(vnum, attid, vartypeid, sublevels_up, vnum, attid); *type_id = vartypeid; return varnode; diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 5009b0326b..f4078c9dfa 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.7 1998/01/20 05:04:24 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.8 1998/01/20 22:12:01 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -67,35 +67,57 @@ static char *attnum_type[SPECIALS] = { /* given refname, return a pointer to the range table entry */ RangeTblEntry * -refnameRangeTableEntry(List *rtable, char *refname) +refnameRangeTableEntry(ParseState *pstate, char *refname) { List *temp; - foreach(temp, rtable) + while (pstate != NULL) { - RangeTblEntry *rte = lfirst(temp); - - if (!strcmp(rte->refname, refname)) - return rte; + foreach(temp, pstate->p_rtable) + { + RangeTblEntry *rte = lfirst(temp); + + if (!strcmp(rte->refname, refname)) + return rte; + } + /* only allow correlated columns in WHERE clause */ + if (pstate->p_in_where_clause) + pstate = pstate->parentParseState; + else break; } return NULL; } /* given refname, return id of variable; position starts with 1 */ int -refnameRangeTablePosn(List *rtable, char *refname) +refnameRangeTablePosn(ParseState *pstate, char *refname, int *sublevels_up) { int index; List *temp; - index = 1; - foreach(temp, rtable) - { - RangeTblEntry *rte = lfirst(temp); + + if (sublevels_up) + *sublevels_up = 0; - if (!strcmp(rte->refname, refname)) - return index; - index++; + while (pstate != NULL) + { + index = 1; + foreach(temp, pstate->p_rtable) + { + RangeTblEntry *rte = lfirst(temp); + + if (!strcmp(rte->refname, refname)) + return index; + index++; + } + /* only allow correlated columns in WHERE clause */ + if (pstate->p_in_where_clause) + { + pstate = pstate->parentParseState; + if (sublevels_up) + (*sublevels_up)++; + } + else break; } return 0; } @@ -110,31 +132,38 @@ colnameRangeTableEntry(ParseState *pstate, char *colname) List *rtable; RangeTblEntry *rte_result; - if (pstate->p_is_rule) - rtable = lnext(lnext(pstate->p_rtable)); - else - rtable = pstate->p_rtable; - rte_result = NULL; - foreach(et, rtable) + while (pstate != NULL) { - RangeTblEntry *rte = lfirst(et); + if (pstate->p_is_rule) + rtable = lnext(lnext(pstate->p_rtable)); + else + rtable = pstate->p_rtable; - /* only entries on outer(non-function?) scope */ - if (!rte->inFromCl && rte != pstate->p_target_rangetblentry) - continue; - - if (get_attnum(rte->relid, colname) != InvalidAttrNumber) + foreach(et, rtable) { - if (rte_result != NULL) + RangeTblEntry *rte = lfirst(et); + + /* only entries on outer(non-function?) scope */ + if (!rte->inFromCl && rte != pstate->p_target_rangetblentry) + continue; + + if (get_attnum(rte->relid, colname) != InvalidAttrNumber) { - if (!pstate->p_is_insert || - rte != pstate->p_target_rangetblentry) - elog(ERROR, "Column %s is ambiguous", colname); + if (rte_result != NULL) + { + if (!pstate->p_is_insert || + rte != pstate->p_target_rangetblentry) + elog(ERROR, "Column %s is ambiguous", colname); + } + else + rte_result = rte; } - else - rte_result = rte; } + /* only allow correlated columns in WHERE clause */ + if (pstate->p_in_where_clause && rte_result == NULL) + pstate = pstate->parentParseState; + else break; } return rte_result; } @@ -152,11 +181,15 @@ addRangeTableEntry(ParseState *pstate, { Relation relation; RangeTblEntry *rte = makeNode(RangeTblEntry); + int sublevels_up; - if (pstate != NULL && - refnameRangeTableEntry(pstate->p_rtable, refname) != NULL) - elog(ERROR, "Table name %s specified more than once", refname); - + if (pstate != NULL) + { + if (refnameRangeTablePosn(pstate, refname, &sublevels_up) != 0 && + (!inFromCl || sublevels_up == 0)) + elog(ERROR, "Table name %s specified more than once", refname); + } + rte->relname = pstrdup(relname); rte->refname = pstrdup(refname); @@ -191,7 +224,6 @@ addRangeTableEntry(ParseState *pstate, /* * expandAll - * makes a list of attributes - * assumes reldesc caching works */ List * expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno) @@ -206,7 +238,7 @@ expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno) int type_len; RangeTblEntry *rte; - rte = refnameRangeTableEntry(pstate->p_rtable, refname); + rte = refnameRangeTableEntry(pstate, refname); if (rte == NULL) rte = addRangeTableEntry(pstate, relname, refname, FALSE, FALSE); @@ -225,7 +257,8 @@ expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno) TargetEntry *te = makeNode(TargetEntry); attrname = pstrdup((rdesc->rd_att->attrs[varattno]->attname).data); - varnode = (Var *) make_var(pstate, refname, attrname, &type_id); + varnode = (Var *) make_var(pstate, rte->relid, refname, + attrname, &type_id); type_len = (int) typeLen(typeidType(type_id)); handleTargetColname(pstate, &resname, refname, attrname); @@ -381,7 +414,7 @@ checkTargetTypes(ParseState *pstate, char *target_colname, return; if (refname != NULL) - rte = refnameRangeTableEntry(pstate->p_rtable, refname); + rte = refnameRangeTableEntry(pstate, refname); else { rte = colnameRangeTableEntry(pstate, colname); diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h index 57583f6773..6345b60024 100644 --- a/src/include/nodes/makefuncs.h +++ b/src/include/nodes/makefuncs.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: makefuncs.h,v 1.5 1997/09/08 02:37:15 momjian Exp $ + * $Id: makefuncs.h,v 1.6 1998/01/20 22:12:13 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -27,6 +27,7 @@ extern Var * makeVar(Index varno, AttrNumber varattno, Oid vartype, + Index varlevelsup, Index varnoold, AttrNumber varoattno); diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 92c2ab00f3..af370b893c 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: primnodes.h,v 1.15 1998/01/19 18:11:10 momjian Exp $ + * $Id: primnodes.h,v 1.16 1998/01/20 22:12:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -104,6 +104,7 @@ typedef struct Expr * (could be INNER or OUTER) * varattno - attribute number of this var, or zero for all * vartype - pg_type tuple oid for the type of this var + * varlevelsup - for subquery variables referencing outer relations * varnoold - keep varno around in case it got changed to INNER/ * OUTER (see match_varid) * varoattno - attribute number of this var @@ -122,6 +123,7 @@ typedef struct Var Index varno; AttrNumber varattno; Oid vartype; + Index varlevelsup; /* erased by upper optimizer */ Index varnoold; /* only used by optimizer */ AttrNumber varoattno; /* only used by optimizer */ } Var; diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h index f09c7d0f86..50580f1036 100644 --- a/src/include/parser/parse_node.h +++ b/src/include/parser/parse_node.h @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: parse_node.h,v 1.6 1998/01/19 05:06:41 momjian Exp $ + * $Id: parse_node.h,v 1.7 1998/01/20 22:12:16 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -45,7 +45,8 @@ typedef struct ParseState extern ParseState *make_parsestate(ParseState *parentParseState); extern Expr *make_op(char *opname, Node *ltree, Node *rtree); -extern Var *make_var(ParseState *pstate, char *refname, char *attrname, Oid *type_id); +extern Var *make_var(ParseState *pstate, Oid relid, char *refname, + char *attrname, Oid *type_id); extern ArrayRef *make_array_ref(Node *expr, List *indirection); extern ArrayRef *make_array_set(Expr *target_expr, diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h index eab72589ff..506fdad46b 100644 --- a/src/include/parser/parse_relation.h +++ b/src/include/parser/parse_relation.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: parse_relation.h,v 1.5 1998/01/20 05:04:56 momjian Exp $ + * $Id: parse_relation.h,v 1.6 1998/01/20 22:12:17 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -20,8 +20,9 @@ #include #include -extern RangeTblEntry *refnameRangeTableEntry(List *rtable, char *refname); -extern int refnameRangeTablePosn(List *rtable, char *refname); +extern RangeTblEntry *refnameRangeTableEntry(ParseState *pstate, char *refname); +extern int refnameRangeTablePosn(ParseState *pstate, + char *refname, int *sublevels_up); extern RangeTblEntry *colnameRangeTableEntry(ParseState *pstate, char *colname); extern RangeTblEntry *addRangeTableEntry(ParseState *pstate, char *relname,