7
7
*
8
8
*
9
9
* 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 $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -52,7 +52,10 @@ static Query *transformUpdateStmt(ParseState *pstate, ReplaceStmt *stmt);
52
52
static Query * transformCursorStmt (ParseState * pstate ,CursorStmt * stmt );
53
53
static Node * handleNestedDots (ParseState * pstate ,Attr * attr ,int * curr_resno );
54
54
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 );
56
59
57
60
static void makeRangeTable (ParseState * pstate ,char * relname ,List * frmList );
58
61
static List * expandAllTables (ParseState * pstate );
@@ -534,7 +537,7 @@ transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
534
537
* here.
535
538
*/
536
539
static Node *
537
- transformExpr (ParseState * pstate ,Node * expr )
540
+ transformExpr (ParseState * pstate ,Node * expr , int precedence )
538
541
{
539
542
Node * result = NULL ;
540
543
@@ -553,11 +556,11 @@ transformExpr(ParseState *pstate, Node *expr)
553
556
while (idx != NIL ) {
554
557
A_Indices * ai = (A_Indices * )lfirst (idx );
555
558
Node * lexpr = NULL ,* uexpr ;
556
- uexpr = transformExpr (pstate ,ai -> uidx );/* must exists */
559
+ uexpr = transformExpr (pstate ,ai -> uidx , precedence );/* must exists */
557
560
if (exprType (uexpr )!= INT4OID )
558
561
elog (WARN ,"array index expressions must be int4's" );
559
562
if (ai -> lidx != NULL ) {
560
- lexpr = transformExpr (pstate ,ai -> lidx );
563
+ lexpr = transformExpr (pstate ,ai -> lidx , precedence );
561
564
if (exprType (lexpr )!= INT4OID )
562
565
elog (WARN ,"array index expressions must be int4's" );
563
566
}
@@ -615,22 +618,22 @@ transformExpr(ParseState *pstate, Node *expr)
615
618
switch (a -> oper ) {
616
619
case OP :
617
620
{
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 );
620
623
result = (Node * )make_op (a -> opname ,lexpr ,rexpr );
621
624
}
622
625
break ;
623
626
case ISNULL :
624
627
{
625
- Node * lexpr = transformExpr (pstate ,a -> lexpr );
628
+ Node * lexpr = transformExpr (pstate ,a -> lexpr , precedence );
626
629
result = ParseFunc (pstate ,
627
630
"NullValue" ,lcons (lexpr ,NIL ),
628
631
& pstate -> p_last_resno );
629
632
}
630
633
break ;
631
634
case NOTNULL :
632
635
{
633
- Node * lexpr = transformExpr (pstate ,a -> lexpr );
636
+ Node * lexpr = transformExpr (pstate ,a -> lexpr , precedence );
634
637
result = ParseFunc (pstate ,
635
638
"NonNullValue" ,lcons (lexpr ,NIL ),
636
639
& pstate -> p_last_resno );
@@ -639,8 +642,8 @@ transformExpr(ParseState *pstate, Node *expr)
639
642
case AND :
640
643
{
641
644
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 );
644
647
if (exprType (lexpr )!= BOOLOID )
645
648
elog (WARN ,
646
649
"left-hand side of AND is type '%s', not bool" ,
@@ -658,8 +661,8 @@ transformExpr(ParseState *pstate, Node *expr)
658
661
case OR :
659
662
{
660
663
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 );
663
666
if (exprType (lexpr )!= BOOLOID )
664
667
elog (WARN ,
665
668
"left-hand side of OR is type '%s', not bool" ,
@@ -677,7 +680,7 @@ transformExpr(ParseState *pstate, Node *expr)
677
680
case NOT :
678
681
{
679
682
Expr * expr = makeNode (Expr );
680
- Node * rexpr = transformExpr (pstate ,a -> rexpr );
683
+ Node * rexpr = transformExpr (pstate ,a -> rexpr , precedence );
681
684
if (exprType (rexpr )!= BOOLOID )
682
685
elog (WARN ,
683
686
"argument to NOT is type '%s', not bool" ,
@@ -692,24 +695,8 @@ transformExpr(ParseState *pstate, Node *expr)
692
695
break ;
693
696
}
694
697
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 );
713
700
break ;
714
701
}
715
702
case T_FuncCall : {
@@ -718,7 +705,7 @@ transformExpr(ParseState *pstate, Node *expr)
718
705
719
706
/* transform the list of arguments */
720
707
foreach (args ,fn -> args )
721
- lfirst (args )= transformExpr (pstate , (Node * )lfirst (args ));
708
+ lfirst (args )= transformExpr (pstate , (Node * )lfirst (args ), precedence );
722
709
result = ParseFunc (pstate ,
723
710
fn -> funcname ,fn -> args ,& pstate -> p_last_resno );
724
711
break ;
@@ -733,6 +720,49 @@ transformExpr(ParseState *pstate, Node *expr)
733
720
return result ;
734
721
}
735
722
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
+
736
766
/*****************************************************************************
737
767
*
738
768
* From Clause
@@ -1011,7 +1041,11 @@ transformTargetList(ParseState *pstate, List *targetlist)
1011
1041
1012
1042
identname = ((Ident * )res -> val )-> name ;
1013
1043
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 );
1015
1049
type_id = exprType (expr );
1016
1050
type_len = tlen (get_id_type (type_id ));
1017
1051
resname = (res -> name ) ?res -> name :identname ;
@@ -1030,7 +1064,7 @@ transformTargetList(ParseState *pstate, List *targetlist)
1030
1064
case T_FuncCall :
1031
1065
case T_A_Const :
1032
1066
case T_A_Expr : {
1033
- Node * expr = transformExpr (pstate , (Node * )res -> val );
1067
+ Node * expr = transformExpr (pstate , (Node * )res -> val , EXPR_COLUMN_FIRST );
1034
1068
1035
1069
handleTargetColname (pstate ,& res -> name ,NULL ,NULL );
1036
1070
/* note indirection has not been transformed */
@@ -1054,13 +1088,13 @@ transformTargetList(ParseState *pstate, List *targetlist)
1054
1088
str = save_str = (char * )palloc (strlen (val )+ MAXDIM * 25 + 2 );
1055
1089
foreach (elt ,res -> indirection ) {
1056
1090
A_Indices * aind = (A_Indices * )lfirst (elt );
1057
- aind -> uidx = transformExpr (pstate ,aind -> uidx );
1091
+ aind -> uidx = transformExpr (pstate ,aind -> uidx , EXPR_COLUMN_FIRST );
1058
1092
if (!IsA (aind -> uidx ,Const ))
1059
1093
elog (WARN ,
1060
1094
"Array Index for Append should be a constant" );
1061
1095
uindx [i ]= ((Const * )aind -> uidx )-> constvalue ;
1062
1096
if (aind -> lidx != NULL ) {
1063
- aind -> lidx = transformExpr (pstate ,aind -> lidx );
1097
+ aind -> lidx = transformExpr (pstate ,aind -> lidx , EXPR_COLUMN_FIRST );
1064
1098
if (!IsA (aind -> lidx ,Const ))
1065
1099
elog (WARN ,
1066
1100
"Array Index for Append should be a constant" );
@@ -1101,8 +1135,8 @@ transformTargetList(ParseState *pstate, List *targetlist)
1101
1135
List * ilist = res -> indirection ;
1102
1136
while (ilist != NIL ) {
1103
1137
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 );
1106
1140
ilist = lnext (ilist );
1107
1141
}
1108
1142
}
@@ -1178,8 +1212,8 @@ transformTargetList(ParseState *pstate, List *targetlist)
1178
1212
List * ilist = att -> indirection ;
1179
1213
while (ilist != NIL ) {
1180
1214
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 );
1183
1217
ilist = lnext (ilist );
1184
1218
}
1185
1219
result = (Node * )make_array_ref (result ,att -> indirection );
@@ -1390,7 +1424,7 @@ make_targetlist_expr(ParseState *pstate,
1390
1424
tent -> expr = expr ;
1391
1425
1392
1426
return tent ;
1393
- }
1427
+ }
1394
1428
1395
1429
1396
1430
/*****************************************************************************
@@ -1412,7 +1446,7 @@ transformWhereClause(ParseState *pstate, Node *a_expr)
1412
1446
if (a_expr == NULL )
1413
1447
return (Node * )NULL ;/* no qualifiers */
1414
1448
1415
- qual = transformExpr (pstate ,a_expr );
1449
+ qual = transformExpr (pstate ,a_expr , EXPR_COLUMN_FIRST );
1416
1450
if (exprType (qual )!= BOOLOID ) {
1417
1451
elog (WARN ,
1418
1452
"where clause must return type bool, not %s" ,
@@ -1633,7 +1667,7 @@ handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno)
1633
1667
Node * retval = NULL ;
1634
1668
1635
1669
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 );
1637
1671
1638
1672
retval =
1639
1673
ParseFunc (pstate ,strVal (lfirst (attr -> attrs )),