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

Commit36ce6d4

Browse files
committed
Support subscripts on bare column names.
1 parentf9e2c7f commit36ce6d4

File tree

1 file changed

+73
-116
lines changed

1 file changed

+73
-116
lines changed

‎src/backend/parser/parse_expr.c

Lines changed: 73 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.52 1999/07/1604:59:32 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.53 1999/07/1622:32:25 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -30,7 +30,10 @@
3030
#include"utils/builtins.h"
3131

3232
staticNode*parser_typecast(Value*expr,TypeName*typename,int32atttypmod);
33-
staticNode*transformIdent(ParseState*pstate,Node*expr,intprecedence);
33+
staticNode*transformAttr(ParseState*pstate,Attr*att,intprecedence);
34+
staticNode*transformIdent(ParseState*pstate,Ident*ident,intprecedence);
35+
staticNode*transformIndirection(ParseState*pstate,Node*basenode,
36+
List*indirection,intprecedence);
3437

3538
/*
3639
* transformExpr -
@@ -51,45 +54,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
5154
{
5255
caseT_Attr:
5356
{
54-
Attr*att= (Attr*)expr;
55-
Node*temp;
56-
57-
/* what if att.attrs == "*"? */
58-
temp=ParseNestedFuncOrColumn(pstate,att,&pstate->p_last_resno,
59-
precedence);
60-
if (att->indirection!=NIL)
61-
{
62-
List*idx=att->indirection;
63-
64-
while (idx!=NIL)
65-
{
66-
A_Indices*ai= (A_Indices*)lfirst(idx);
67-
Node*lexpr=NULL,
68-
*uexpr;
69-
70-
uexpr=transformExpr(pstate,ai->uidx,precedence);/* must exists */
71-
if (exprType(uexpr)!=INT4OID)
72-
elog(ERROR,"array index expressions must be int4's");
73-
if (ai->lidx!=NULL)
74-
{
75-
lexpr=transformExpr(pstate,ai->lidx,precedence);
76-
if (exprType(lexpr)!=INT4OID)
77-
elog(ERROR,"array index expressions must be int4's");
78-
}
79-
ai->lidx=lexpr;
80-
ai->uidx=uexpr;
81-
82-
/*
83-
* note we reuse the list of indices, make sure we
84-
* don't free them! Otherwise, make a new list
85-
* here
86-
*/
87-
idx=lnext(idx);
88-
}
89-
result= (Node*)make_array_ref(temp,att->indirection);
90-
}
91-
else
92-
result=temp;
57+
result=transformAttr(pstate, (Attr*)expr,precedence);
9358
break;
9459
}
9560
caseT_A_Const:
@@ -106,12 +71,10 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
10671
caseT_ParamNo:
10772
{
10873
ParamNo*pno= (ParamNo*)expr;
109-
Oidtoid;
110-
intparamno;
74+
intparamno=pno->number;
75+
Oidtoid=param_type(paramno);
11176
Param*param;
11277

113-
paramno=pno->number;
114-
toid=param_type(paramno);
11578
if (!OidIsValid(toid))
11679
elog(ERROR,"Parameter '$%d' is out of range",paramno);
11780
param=makeNode(Param);
@@ -120,40 +83,8 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
12083
param->paramname="<unnamed>";
12184
param->paramtype= (Oid)toid;
12285
param->param_tlist= (List*)NULL;
123-
124-
if (pno->indirection!=NIL)
125-
{
126-
List*idx=pno->indirection;
127-
128-
while (idx!=NIL)
129-
{
130-
A_Indices*ai= (A_Indices*)lfirst(idx);
131-
Node*lexpr=NULL,
132-
*uexpr;
133-
134-
uexpr=transformExpr(pstate,ai->uidx,precedence);/* must exists */
135-
if (exprType(uexpr)!=INT4OID)
136-
elog(ERROR,"array index expressions must be int4's");
137-
if (ai->lidx!=NULL)
138-
{
139-
lexpr=transformExpr(pstate,ai->lidx,precedence);
140-
if (exprType(lexpr)!=INT4OID)
141-
elog(ERROR,"array index expressions must be int4's");
142-
}
143-
ai->lidx=lexpr;
144-
ai->uidx=uexpr;
145-
146-
/*
147-
* note we reuse the list of indices, make sure we
148-
* don't free them! Otherwise, make a new list
149-
* here
150-
*/
151-
idx=lnext(idx);
152-
}
153-
result= (Node*)make_array_ref((Node*)param,pno->indirection);
154-
}
155-
else
156-
result= (Node*)param;
86+
result=transformIndirection(pstate, (Node*)param,
87+
pno->indirection,precedence);
15788
break;
15889
}
15990
caseT_A_Expr:
@@ -247,12 +178,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
247178
}
248179
caseT_Ident:
249180
{
250-
251-
/*
252-
* look for a column name or a relation name (the default
253-
* behavior)
254-
*/
255-
result=transformIdent(pstate,expr,precedence);
181+
result=transformIdent(pstate, (Ident*)expr,precedence);
256182
break;
257183
}
258184
caseT_FuncCall:
@@ -544,48 +470,79 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
544470
}
545471

546472
staticNode*
547-
transformIdent(ParseState*pstate,Node*expr,intprecedence)
473+
transformIndirection(ParseState*pstate,Node*basenode,
474+
List*indirection,intprecedence)
548475
{
549-
Ident*ident= (Ident*)expr;
550-
RangeTblEntry*rte;
551-
Node*column_result,
552-
*relation_result,
553-
*result;
476+
List*idx;
554477

555-
column_result=relation_result=result=0;
556-
/* try to find the ident as a column */
557-
if ((rte=colnameRangeTableEntry(pstate,ident->name))!=NULL)
478+
if (indirection==NIL)
479+
returnbasenode;
480+
foreach (idx,indirection)
558481
{
559-
Attr*att=makeNode(Attr);
482+
A_Indices*ai= (A_Indices*)lfirst(idx);
483+
Node*lexpr=NULL,
484+
*uexpr;
560485

561-
/* we add the relation name for them */
562-
att->relname=rte->refname;
563-
att->attrs=lcons(makeString(ident->name),NIL);
564-
column_result= (Node*)ParseNestedFuncOrColumn(pstate,att,
565-
&pstate->p_last_resno,precedence);
486+
/* uidx is always present, but lidx might be null */
487+
if (ai->lidx!=NULL)
488+
{
489+
lexpr=transformExpr(pstate,ai->lidx,precedence);
490+
if (exprType(lexpr)!=INT4OID)
491+
elog(ERROR,"array index expressions must be int4's");
492+
}
493+
uexpr=transformExpr(pstate,ai->uidx,precedence);
494+
if (exprType(uexpr)!=INT4OID)
495+
elog(ERROR,"array index expressions must be int4's");
496+
ai->lidx=lexpr;
497+
ai->uidx=uexpr;
498+
/*
499+
* note we reuse the list of A_Indices nodes, make sure
500+
* we don't free them! Otherwise, make a new list here
501+
*/
566502
}
503+
return (Node*)make_array_ref(basenode,indirection);
504+
}
505+
506+
staticNode*
507+
transformAttr(ParseState*pstate,Attr*att,intprecedence)
508+
{
509+
Node*basenode;
567510

568-
/* try to find the ident as a relation */
569-
if (refnameRangeTableEntry(pstate,ident->name)!=NULL)
511+
/* what if att->attrs == "*"? */
512+
basenode=ParseNestedFuncOrColumn(pstate,att,&pstate->p_last_resno,
513+
precedence);
514+
returntransformIndirection(pstate,basenode,
515+
att->indirection,precedence);
516+
}
517+
518+
staticNode*
519+
transformIdent(ParseState*pstate,Ident*ident,intprecedence)
520+
{
521+
Node*result=NULL;
522+
RangeTblEntry*rte;
523+
524+
/* try to find the ident as a relation ... but not if subscripts appear */
525+
if (ident->indirection==NIL&&
526+
refnameRangeTableEntry(pstate,ident->name)!=NULL)
570527
{
571528
ident->isRel= TRUE;
572-
relation_result= (Node*)ident;
529+
result= (Node*)ident;
573530
}
574531

575-
/* choose the right result based on the precedence */
576-
if (precedence==EXPR_COLUMN_FIRST)
532+
if (result==NULL||precedence==EXPR_COLUMN_FIRST)
577533
{
578-
if (column_result)
579-
result=column_result;
580-
else
581-
result=relation_result;
582-
}
583-
else
584-
{
585-
if (relation_result)
586-
result=relation_result;
587-
else
588-
result=column_result;
534+
/* try to find the ident as a column */
535+
if ((rte=colnameRangeTableEntry(pstate,ident->name))!=NULL)
536+
{
537+
/* Convert it to a fully qualified Attr, and transform that */
538+
Attr*att=makeNode(Attr);
539+
540+
att->relname=rte->refname;
541+
att->paramNo=NULL;
542+
att->attrs=lcons(makeString(ident->name),NIL);
543+
att->indirection=ident->indirection;
544+
returntransformAttr(pstate,att,precedence);
545+
}
589546
}
590547

591548
if (result==NULL)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp