Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1278269

Browse files
committed
From: Dan McGuirk <mcguirk@indirect.com>
Subject: [HACKERS] equal column and table name patchThis fixes a bug where selects fail when there is a column with the samename as the table it's a part of.
1 parente4949f9 commit1278269

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
staticQuery*transformCursorStmt(ParseState*pstate,CursorStmt*stmt);
5353
staticNode*handleNestedDots(ParseState*pstate,Attr*attr,int*curr_resno);
5454

55-
staticNode*transformExpr(ParseState*pstate,Node*expr);
55+
#defineEXPR_COLUMN_FIRST 1
56+
#defineEXPR_RELATION_FIRST 2
57+
staticNode*transformExpr(ParseState*pstate,Node*expr,intprecedence);
58+
staticNode*transformIdent(ParseState*pstate,Node*expr,intprecedence);
5659

5760
staticvoidmakeRangeTable(ParseState*pstate,char*relname,List*frmList);
5861
staticList*expandAllTables(ParseState*pstate);
@@ -534,7 +537,7 @@ transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
534537
* here.
535538
*/
536539
staticNode*
537-
transformExpr(ParseState*pstate,Node*expr)
540+
transformExpr(ParseState*pstate,Node*expr,intprecedence)
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
caseOP:
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
caseISNULL:
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
caseNOTNULL:
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
caseAND:
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
caseOR:
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
caseNOT:
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
caseT_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-
elseif ((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
caseT_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
returnresult;
734721
}
735722

723+
staticNode*
724+
transformIdent(ParseState*pstate,Node*expr,intprecedence)
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+
returnresult;
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
caseT_FuncCall:
10311065
caseT_A_Const:
10321066
caseT_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
returntent;
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)

[8]ページ先頭

©2009-2025 Movatter.jp