8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.74 2000/03/17 05:29:05 tgl Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.75 2000/03/19 07:13:58 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -61,10 +61,27 @@ parse_expr_init(void)
61
61
62
62
/*
63
63
* transformExpr -
64
- * analyze and transform expressions. Type checking and type casting is
64
+ * Analyze and transform expressions. Type checking and type casting is
65
65
* done here. The optimizer and the executor cannot handle the original
66
66
* (raw) expressions collected by the parse tree. Hence the transformation
67
67
* here.
68
+ *
69
+ * NOTE: there are various cases in which this routine will get applied to
70
+ * an already-transformed expression. Some examples:
71
+ * 1. At least one construct (BETWEEN/AND) puts the same nodes
72
+ * into two branches of the parse tree; hence, some nodes
73
+ * are transformed twice.
74
+ * 2. Another way it can happen is that coercion of an operator or
75
+ * function argument to the required type (via coerce_type())
76
+ * can apply transformExpr to an already-transformed subexpression.
77
+ * An example here is "SELECT count(*) + 1.0 FROM table".
78
+ * While it might be possible to eliminate these cases, the path of
79
+ * least resistance so far has been to ensure that transformExpr() does
80
+ * no damage if applied to an already-transformed tree. This is pretty
81
+ * easy for cases where the transformation replaces one node type with
82
+ * another, such as A_Const => Const; we just do nothing when handed
83
+ * a Const. More care is needed for node types that are used as both
84
+ * input and output of transformExpr; see SubLink for example.
68
85
*/
69
86
Node *
70
87
transformExpr (ParseState * pstate , Node * expr , int precedence )
@@ -254,6 +271,12 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
254
271
List * qtrees ;
255
272
Query * qtree ;
256
273
274
+ /* If we already transformed this node, do nothing */
275
+ if (IsA (sublink -> subselect , Query ))
276
+ {
277
+ result = expr ;
278
+ break ;
279
+ }
257
280
pstate -> p_hasSubLinks = true;
258
281
qtrees = parse_analyze (lcons (sublink -> subselect , NIL ), pstate );
259
282
if (length (qtrees ) != 1 )
@@ -390,7 +413,9 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
390
413
/*
391
414
* It's not shorthand anymore, so drop the implicit
392
415
* argument. This is necessary to keep the executor from
393
- * seeing an untransformed expression...
416
+ * seeing an untransformed expression... not to mention
417
+ * keeping a re-application of transformExpr from doing
418
+ * the wrong thing.
394
419
*/
395
420
c -> arg = NULL ;
396
421
@@ -528,22 +553,14 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
528
553
break ;
529
554
}
530
555
531
- /* Some nodes do _not_ come from the original parse tree,
532
- * but result from parser transformation in this phase.
533
- * At least one construct (BETWEEN/AND) puts the same nodes
534
- * into two branches of the parse tree; hence, some nodes
535
- * are transformed twice.
536
- * Another way it can happen is that coercion of an operator or
537
- * function argument to the required type (via coerce_type())
538
- * can apply transformExpr to an already-transformed subexpression.
539
- * An example here is "SELECT count(*) + 1.0 FROM table".
540
- * Thus, we can see node types in this routine that do not appear in the
541
- * original parse tree. Assume they are already transformed, and just
542
- * pass them through.
543
- * Do any other node types need to be accepted? For now we are taking
544
- * a conservative approach, and only accepting node types that are
545
- * demonstrably necessary to accept.
546
- */
556
+ /*
557
+ * Quietly accept node types that may be presented when we are called
558
+ * on an already-transformed tree.
559
+ *
560
+ * Do any other node types need to be accepted? For now we are taking
561
+ * a conservative approach, and only accepting node types that are
562
+ * demonstrably necessary to accept.
563
+ */
547
564
case T_Expr :
548
565
case T_Var :
549
566
case T_Const :
@@ -555,6 +572,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
555
572
result = (Node * ) expr ;
556
573
break ;
557
574
}
575
+
558
576
default :
559
577
/* should not reach here */
560
578
elog (ERROR , "transformExpr: does not know how to transform node %d"
0 commit comments