Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1278269

Browse files
committed
From: Dan McGuirk <mcguirk@indirect.com>
Subject: [HACKERS] equal column and table name patch This fixes a bug where selects fail when there is a column with the same name as the table it's a part of.
1 parent e4949f9 commit 1278269

File tree

1 file changed

+78
-44
lines changed

1 file changed

+78
-44
lines changed

src/backend/parser/analyze.c

Lines changed: 78 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.22 1997/03/02 01:02:48 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.23 1997/03/12 20:51:33 scrappy Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -52,7 +52,10 @@ static Query *transformUpdateStmt(ParseState *pstate, ReplaceStmt *stmt);
5252
static Query *transformCursorStmt(ParseState *pstate, CursorStmt *stmt);
5353
static Node *handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno);
5454

55-
static Node *transformExpr(ParseState *pstate, Node *expr);
55+
#define EXPR_COLUMN_FIRST 1
56+
#define EXPR_RELATION_FIRST 2
57+
static Node *transformExpr(ParseState *pstate, Node *expr, int precedence);
58+
static Node *transformIdent(ParseState *pstate, Node *expr, int precedence);
5659

5760
static void makeRangeTable(ParseState *pstate, char *relname, List *frmList);
5861
static List *expandAllTables(ParseState *pstate);
@@ -534,7 +537,7 @@ transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
534537
* here.
535538
*/
536539
static Node *
537-
transformExpr(ParseState *pstate, Node *expr)
540+
transformExpr(ParseState *pstate, Node *expr, int precedence)
538541
{
539542
Node *result = NULL;
540543

@@ -553,11 +556,11 @@ transformExpr(ParseState *pstate, Node *expr)
553556
while(idx!=NIL) {
554557
A_Indices *ai = (A_Indices *)lfirst(idx);
555558
Node *lexpr=NULL, *uexpr;
556-
uexpr = transformExpr(pstate, ai->uidx); /* must exists */
559+
uexpr = transformExpr(pstate, ai->uidx, precedence); /* must exists */
557560
if (exprType(uexpr) != INT4OID)
558561
elog(WARN, "array index expressions must be int4's");
559562
if (ai->lidx != NULL) {
560-
lexpr = transformExpr(pstate, ai->lidx);
563+
lexpr = transformExpr(pstate, ai->lidx, precedence);
561564
if (exprType(lexpr) != INT4OID)
562565
elog(WARN, "array index expressions must be int4's");
563566
}
@@ -615,22 +618,22 @@ transformExpr(ParseState *pstate, Node *expr)
615618
switch(a->oper) {
616619
case OP:
617620
{
618-
Node *lexpr = transformExpr(pstate, a->lexpr);
619-
Node *rexpr = transformExpr(pstate, a->rexpr);
621+
Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
622+
Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
620623
result = (Node *)make_op(a->opname, lexpr, rexpr);
621624
}
622625
break;
623626
case ISNULL:
624627
{
625-
Node *lexpr = transformExpr(pstate, a->lexpr);
628+
Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
626629
result = ParseFunc(pstate,
627630
"NullValue", lcons(lexpr, NIL),
628631
&pstate->p_last_resno);
629632
}
630633
break;
631634
case NOTNULL:
632635
{
633-
Node *lexpr = transformExpr(pstate, a->lexpr);
636+
Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
634637
result = ParseFunc(pstate,
635638
"NonNullValue", lcons(lexpr, NIL),
636639
&pstate->p_last_resno);
@@ -639,8 +642,8 @@ transformExpr(ParseState *pstate, Node *expr)
639642
case AND:
640643
{
641644
Expr *expr = makeNode(Expr);
642-
Node *lexpr = transformExpr(pstate, a->lexpr);
643-
Node *rexpr = transformExpr(pstate, a->rexpr);
645+
Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
646+
Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
644647
if (exprType(lexpr) != BOOLOID)
645648
elog(WARN,
646649
"left-hand side of AND is type '%s', not bool",
@@ -658,8 +661,8 @@ transformExpr(ParseState *pstate, Node *expr)
658661
case OR:
659662
{
660663
Expr *expr = makeNode(Expr);
661-
Node *lexpr = transformExpr(pstate, a->lexpr);
662-
Node *rexpr = transformExpr(pstate, a->rexpr);
664+
Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
665+
Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
663666
if (exprType(lexpr) != BOOLOID)
664667
elog(WARN,
665668
"left-hand side of OR is type '%s', not bool",
@@ -677,7 +680,7 @@ transformExpr(ParseState *pstate, Node *expr)
677680
case NOT:
678681
{
679682
Expr *expr = makeNode(Expr);
680-
Node *rexpr = transformExpr(pstate, a->rexpr);
683+
Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
681684
if (exprType(rexpr) != BOOLOID)
682685
elog(WARN,
683686
"argument to NOT is type '%s', not bool",
@@ -692,24 +695,8 @@ transformExpr(ParseState *pstate, Node *expr)
692695
break;
693696
}
694697
case T_Ident: {
695-
Ident *ident = (Ident*)expr;
696-
RangeTblEntry *rte;
697-
698-
/* could be a column name or a relation_name */
699-
if (refnameRangeTableEntry(pstate->p_rtable, ident->name) != NULL) {
700-
ident->isRel = TRUE;
701-
result = (Node*)ident;
702-
}
703-
else if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL)
704-
{
705-
Attr *att = makeNode(Attr);
706-
707-
att->relname = rte->refname;
708-
att->attrs = lcons(makeString(ident->name), NIL);
709-
result =
710-
(Node*)handleNestedDots(pstate, att, &pstate->p_last_resno);
711-
} else
712-
elog(WARN, "attribute \"%s\" not found", ident->name);
698+
/* look for a column name or a relation name (the default behavior) */
699+
result = transformIdent(pstate, expr, precedence);
713700
break;
714701
}
715702
case T_FuncCall: {
@@ -718,7 +705,7 @@ transformExpr(ParseState *pstate, Node *expr)
718705

719706
/* transform the list of arguments */
720707
foreach(args, fn->args)
721-
lfirst(args) = transformExpr(pstate, (Node*)lfirst(args));
708+
lfirst(args) = transformExpr(pstate, (Node*)lfirst(args), precedence);
722709
result = ParseFunc(pstate,
723710
fn->funcname, fn->args, &pstate->p_last_resno);
724711
break;
@@ -733,6 +720,49 @@ transformExpr(ParseState *pstate, Node *expr)
733720
return result;
734721
}
735722

723+
static Node *
724+
transformIdent(ParseState *pstate, Node *expr, int precedence)
725+
{
726+
Ident *ident = (Ident*)expr;
727+
RangeTblEntry *rte;
728+
Node *column_result, *relation_result, *result;
729+
730+
column_result = relation_result = result = 0;
731+
/* try to find the ident as a column */
732+
if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL) {
733+
Attr *att = makeNode(Attr);
734+
735+
att->relname = rte->refname;
736+
att->attrs = lcons(makeString(ident->name), NIL);
737+
column_result =
738+
(Node*)handleNestedDots(pstate, att, &pstate->p_last_resno);
739+
}
740+
741+
/* try to find the ident as a relation */
742+
if (refnameRangeTableEntry(pstate->p_rtable, ident->name) != NULL) {
743+
ident->isRel = TRUE;
744+
relation_result = (Node*)ident;
745+
}
746+
747+
/* choose the right result based on the precedence */
748+
if(precedence == EXPR_COLUMN_FIRST) {
749+
if(column_result)
750+
result = column_result;
751+
else
752+
result = relation_result;
753+
} else {
754+
if(relation_result)
755+
result = relation_result;
756+
else
757+
result = column_result;
758+
}
759+
760+
if(result == NULL)
761+
elog(WARN, "attribute \"%s\" not found", ident->name);
762+
763+
return result;
764+
}
765+
736766
/*****************************************************************************
737767
*
738768
* From Clause
@@ -1011,7 +1041,11 @@ transformTargetList(ParseState *pstate, List *targetlist)
10111041

10121042
identname = ((Ident*)res->val)->name;
10131043
handleTargetColname(pstate, &res->name, NULL, res->name);
1014-
expr = transformExpr(pstate, (Node*)res->val);
1044+
1045+
/* here we want to look for column names only, not relation */
1046+
/* names (even though they can be stored in Ident nodes, */
1047+
/* too) */
1048+
expr = transformIdent(pstate, (Node*)res->val, EXPR_COLUMN_FIRST);
10151049
type_id = exprType(expr);
10161050
type_len = tlen(get_id_type(type_id));
10171051
resname = (res->name) ? res->name : identname;
@@ -1030,7 +1064,7 @@ transformTargetList(ParseState *pstate, List *targetlist)
10301064
case T_FuncCall:
10311065
case T_A_Const:
10321066
case T_A_Expr: {
1033-
Node *expr = transformExpr(pstate, (Node *)res->val);
1067+
Node *expr = transformExpr(pstate, (Node *)res->val, EXPR_COLUMN_FIRST);
10341068

10351069
handleTargetColname(pstate, &res->name, NULL, NULL);
10361070
/* note indirection has not been transformed */
@@ -1054,13 +1088,13 @@ transformTargetList(ParseState *pstate, List *targetlist)
10541088
str = save_str = (char*)palloc(strlen(val) + MAXDIM * 25 + 2);
10551089
foreach(elt, res->indirection) {
10561090
A_Indices *aind = (A_Indices *)lfirst(elt);
1057-
aind->uidx = transformExpr(pstate, aind->uidx);
1091+
aind->uidx = transformExpr(pstate, aind->uidx, EXPR_COLUMN_FIRST);
10581092
if (!IsA(aind->uidx,Const))
10591093
elog(WARN,
10601094
"Array Index for Append should be a constant");
10611095
uindx[i] = ((Const *)aind->uidx)->constvalue;
10621096
if (aind->lidx!=NULL) {
1063-
aind->lidx = transformExpr(pstate, aind->lidx);
1097+
aind->lidx = transformExpr(pstate, aind->lidx, EXPR_COLUMN_FIRST);
10641098
if (!IsA(aind->lidx,Const))
10651099
elog(WARN,
10661100
"Array Index for Append should be a constant");
@@ -1101,8 +1135,8 @@ transformTargetList(ParseState *pstate, List *targetlist)
11011135
List *ilist = res->indirection;
11021136
while (ilist!=NIL) {
11031137
A_Indices *ind = lfirst(ilist);
1104-
ind->lidx = transformExpr(pstate, ind->lidx);
1105-
ind->uidx = transformExpr(pstate, ind->uidx);
1138+
ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1139+
ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
11061140
ilist = lnext(ilist);
11071141
}
11081142
}
@@ -1178,8 +1212,8 @@ transformTargetList(ParseState *pstate, List *targetlist)
11781212
List *ilist = att->indirection;
11791213
while (ilist!=NIL) {
11801214
A_Indices *ind = lfirst(ilist);
1181-
ind->lidx = transformExpr(pstate, ind->lidx);
1182-
ind->uidx = transformExpr(pstate, ind->uidx);
1215+
ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1216+
ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
11831217
ilist = lnext(ilist);
11841218
}
11851219
result = (Node*)make_array_ref(result, att->indirection);
@@ -1390,7 +1424,7 @@ make_targetlist_expr(ParseState *pstate,
13901424
tent->expr = expr;
13911425

13921426
return tent;
1393-
}
1427+
}
13941428

13951429

13961430
/*****************************************************************************
@@ -1412,7 +1446,7 @@ transformWhereClause(ParseState *pstate, Node *a_expr)
14121446
if (a_expr == NULL)
14131447
return (Node *)NULL; /* no qualifiers */
14141448

1415-
qual = transformExpr(pstate, a_expr);
1449+
qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST);
14161450
if (exprType(qual) != BOOLOID) {
14171451
elog(WARN,
14181452
"where clause must return type bool, not %s",
@@ -1633,7 +1667,7 @@ handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno)
16331667
Node *retval = NULL;
16341668

16351669
if (attr->paramNo != NULL) {
1636-
Param *param = (Param *)transformExpr(pstate, (Node*)attr->paramNo);
1670+
Param *param = (Param *)transformExpr(pstate, (Node*)attr->paramNo, EXPR_RELATION_FIRST);
16371671

16381672
retval =
16391673
ParseFunc(pstate, strVal(lfirst(attr->attrs)),

0 commit comments

Comments
 (0)