mirror of
https://github.com/postgres/postgres.git
synced 2025-05-17 06:41:24 +03:00
Tweak findTargetlistEntry so that bare names occurring in GROUP BY clauses
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.
This commit is contained in:
parent
2510c867d6
commit
9086c46f22
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.124 2003/09/26 15:27:35 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.124.2.1 2004/04/18 18:13:31 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1112,10 +1112,18 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
|
|||||||
* is a matching column. If so, fall through to let
|
* is a matching column. If so, fall through to let
|
||||||
* transformExpr() do the rest. NOTE: if name could refer
|
* transformExpr() do the rest. NOTE: if name could refer
|
||||||
* ambiguously to more than one column name exposed by FROM,
|
* 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.
|
* 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;
|
name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.163 2003/09/26 15:27:35 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.163.2.1 2004/04/18 18:13:31 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -990,7 +990,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
|
|||||||
char *name = strVal(lfirst(cref->fields));
|
char *name = strVal(lfirst(cref->fields));
|
||||||
|
|
||||||
/* Try to identify as an unqualified column */
|
/* Try to identify as an unqualified column */
|
||||||
node = colnameToVar(pstate, name);
|
node = colNameToVar(pstate, name, false);
|
||||||
|
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.90 2003/09/25 06:58:01 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.90.2.1 2004/04/18 18:13:31 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -513,13 +513,14 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* colnameToVar
|
* colNameToVar
|
||||||
* Search for an unqualified column name.
|
* Search for an unqualified column name.
|
||||||
* If found, return the appropriate Var node (or expression).
|
* If found, return the appropriate Var node (or expression).
|
||||||
* If not found, return NULL. If the name proves ambiguous, raise error.
|
* 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 *
|
Node *
|
||||||
colnameToVar(ParseState *pstate, char *colname)
|
colNameToVar(ParseState *pstate, char *colname, bool localonly)
|
||||||
{
|
{
|
||||||
Node *result = NULL;
|
Node *result = NULL;
|
||||||
ParseState *orig_pstate = pstate;
|
ParseState *orig_pstate = pstate;
|
||||||
@ -576,8 +577,8 @@ colnameToVar(ParseState *pstate, char *colname)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != NULL)
|
if (result != NULL || localonly)
|
||||||
break; /* found */
|
break; /* found, or don't want to look at parent */
|
||||||
|
|
||||||
pstate = pstate->parentParseState;
|
pstate = pstate->parentParseState;
|
||||||
levels_up++;
|
levels_up++;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: parse_relation.h,v 1.41 2003/08/04 02:40:14 momjian Exp $
|
* $Id: parse_relation.h,v 1.41.4.1 2004/04/18 18:13:31 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -27,7 +27,7 @@ extern void checkNameSpaceConflicts(ParseState *pstate, Node *namespace1,
|
|||||||
extern int RTERangeTablePosn(ParseState *pstate,
|
extern int RTERangeTablePosn(ParseState *pstate,
|
||||||
RangeTblEntry *rte,
|
RangeTblEntry *rte,
|
||||||
int *sublevels_up);
|
int *sublevels_up);
|
||||||
extern Node *colnameToVar(ParseState *pstate, char *colname);
|
extern Node *colNameToVar(ParseState *pstate, char *colname, bool localonly);
|
||||||
extern Node *qualifiedNameToVar(ParseState *pstate,
|
extern Node *qualifiedNameToVar(ParseState *pstate,
|
||||||
char *schemaname,
|
char *schemaname,
|
||||||
char *refname,
|
char *refname,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user