Tweak findTargetlistEntry so that bare names occurring in GROUP BY clauses
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 18 Apr 2004 18:12:58 +0000 (18:12 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 18 Apr 2004 18:12:58 +0000 (18:12 +0000)
are sought first as local FROM columns, then as local SELECT-list aliases,
and finally as outer FROM columns; the former behavior made outer FROM
columns take precedence over aliases.  This does not change spec
conformance because SQL99 allows only the first case anyway, and it seems
more useful and self-consistent.  Per gripe from Dennis Bjorklund 2004-04-05.

src/backend/parser/parse_clause.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_relation.c
src/include/parser/parse_relation.h

index 6f7a004a6caebf678a8edb9bc630762436853437..c15dd9b78922d269952b28c0cf995ecbacb1aadc 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.127 2004/01/23 02:13:12 neilc Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.128 2004/04/18 18:12:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1140,10 +1140,18 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
             * is a matching column.  If so, fall through to let
             * transformExpr() do the rest.  NOTE: if name could refer
             * ambiguously to more than one column name exposed by FROM,
-            * colnameToVar will ereport(ERROR).  That's just what we want
+            * colNameToVar will ereport(ERROR).  That's just what we want
             * here.
+            *
+            * Small tweak for 7.4.3: ignore matches in upper query levels.
+            * This effectively changes the search order for bare names to
+            * (1) local FROM variables, (2) local targetlist aliases,
+            * (3) outer FROM variables, whereas before it was (1) (3) (2).
+            * SQL92 and SQL99 do not allow GROUPing BY an outer reference,
+            * so this breaks no cases that are legal per spec, and it
+            * seems a more self-consistent behavior.
             */
-           if (colnameToVar(pstate, name) != NULL)
+           if (colNameToVar(pstate, name, true) != NULL)
                name = NULL;
        }
 
index acee2b300e419e01c162bd3bbd105c92860a5156..2747ec3ed4386a878b9e27a839908a7e52d33426 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.168 2004/04/02 19:06:58 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.169 2004/04/18 18:12:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -966,7 +966,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
                char       *name = strVal(lfirst(cref->fields));
 
                /* Try to identify as an unqualified column */
-               node = colnameToVar(pstate, name);
+               node = colNameToVar(pstate, name, false);
 
                if (node == NULL)
                {
index 4df92ee310cdd9bdc7cb8e95f30fa0dac3ac63af..de4bf093ee950589320113bd8bd226b7c65af991 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.93 2004/04/02 19:06:58 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.94 2004/04/18 18:12:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -531,13 +531,14 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname)
 }
 
 /*
- * colnameToVar
+ * colNameToVar
  *   Search for an unqualified column name.
  *   If found, return the appropriate Var node (or expression).
  *   If not found, return NULL.  If the name proves ambiguous, raise error.
+ *   If localonly is true, only names in the innermost query are considered.
  */
 Node *
-colnameToVar(ParseState *pstate, char *colname)
+colNameToVar(ParseState *pstate, char *colname, bool localonly)
 {
    Node       *result = NULL;
    ParseState *orig_pstate = pstate;
@@ -594,8 +595,8 @@ colnameToVar(ParseState *pstate, char *colname)
            }
        }
 
-       if (result != NULL)
-           break;              /* found */
+       if (result != NULL || localonly)
+           break;              /* found, or don't want to look at parent */
 
        pstate = pstate->parentParseState;
        levels_up++;
index 0fa75d0297ddf56d1f6d7674e414dfd4762814ce..724639dd96ad56d820b6fb891a39e96d4f12e83a 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.43 2004/04/02 19:07:02 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.44 2004/04/18 18:12:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -32,7 +32,7 @@ extern RangeTblEntry *GetRTEByRangeTablePosn(ParseState *pstate,
                                             int sublevels_up);
 extern Node *scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
                              char *colname);
-extern Node *colnameToVar(ParseState *pstate, char *colname);
+extern Node *colNameToVar(ParseState *pstate, char *colname, bool localonly);
 extern Node *qualifiedNameToVar(ParseState *pstate,
                   char *schemaname,
                   char *refname,