7
7
*
8
8
*
9
9
* IDENTIFICATION
10
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.52 1999/07/16 04:59:32 momjian Exp $
10
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.53 1999/07/16 22:32:25 tgl Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
30
30
#include "utils/builtins.h"
31
31
32
32
static Node * parser_typecast (Value * expr , TypeName * typename , int32 atttypmod );
33
- static Node * transformIdent (ParseState * pstate , Node * expr , int precedence );
33
+ static Node * transformAttr (ParseState * pstate , Attr * att , int precedence );
34
+ static Node * transformIdent (ParseState * pstate , Ident * ident , int precedence );
35
+ static Node * transformIndirection (ParseState * pstate , Node * basenode ,
36
+ List * indirection , int precedence );
34
37
35
38
/*
36
39
* transformExpr -
@@ -51,45 +54,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
51
54
{
52
55
case T_Attr :
53
56
{
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 );
93
58
break ;
94
59
}
95
60
case T_A_Const :
@@ -106,12 +71,10 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
106
71
case T_ParamNo :
107
72
{
108
73
ParamNo * pno = (ParamNo * ) expr ;
109
- Oid toid ;
110
- int paramno ;
74
+ int paramno = pno -> number ;
75
+ Oid toid = param_type ( paramno ) ;
111
76
Param * param ;
112
77
113
- paramno = pno -> number ;
114
- toid = param_type (paramno );
115
78
if (!OidIsValid (toid ))
116
79
elog (ERROR , "Parameter '$%d' is out of range" , paramno );
117
80
param = makeNode (Param );
@@ -120,40 +83,8 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
120
83
param -> paramname = "<unnamed>" ;
121
84
param -> paramtype = (Oid ) toid ;
122
85
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 );
157
88
break ;
158
89
}
159
90
case T_A_Expr :
@@ -247,12 +178,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
247
178
}
248
179
case T_Ident :
249
180
{
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 );
256
182
break ;
257
183
}
258
184
case T_FuncCall :
@@ -544,48 +470,79 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
544
470
}
545
471
546
472
static Node *
547
- transformIdent (ParseState * pstate , Node * expr , int precedence )
473
+ transformIndirection (ParseState * pstate , Node * basenode ,
474
+ List * indirection , int precedence )
548
475
{
549
- Ident * ident = (Ident * ) expr ;
550
- RangeTblEntry * rte ;
551
- Node * column_result ,
552
- * relation_result ,
553
- * result ;
476
+ List * idx ;
554
477
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
+ return basenode ;
480
+ foreach ( idx , indirection )
558
481
{
559
- Attr * att = makeNode (Attr );
482
+ A_Indices * ai = (A_Indices * ) lfirst (idx );
483
+ Node * lexpr = NULL ,
484
+ * uexpr ;
560
485
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
+ */
566
502
}
503
+ return (Node * ) make_array_ref (basenode , indirection );
504
+ }
505
+
506
+ static Node *
507
+ transformAttr (ParseState * pstate , Attr * att , int precedence )
508
+ {
509
+ Node * basenode ;
567
510
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
+ return transformIndirection (pstate , basenode ,
515
+ att -> indirection , precedence );
516
+ }
517
+
518
+ static Node *
519
+ transformIdent (ParseState * pstate , Ident * ident , int precedence )
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 )
570
527
{
571
528
ident -> isRel = TRUE;
572
- relation_result = (Node * ) ident ;
529
+ result = (Node * ) ident ;
573
530
}
574
531
575
- /* choose the right result based on the precedence */
576
- if (precedence == EXPR_COLUMN_FIRST )
532
+ if (result == NULL || precedence == EXPR_COLUMN_FIRST )
577
533
{
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
+ return transformAttr (pstate , att , precedence );
545
+ }
589
546
}
590
547
591
548
if (result == NULL )
0 commit comments