88 *
99 *
1010 * 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 $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -61,10 +61,27 @@ parse_expr_init(void)
6161
6262/*
6363 * transformExpr -
64- *analyze and transform expressions. Type checking and type casting is
64+ *Analyze and transform expressions. Type checking and type casting is
6565 * done here. The optimizer and the executor cannot handle the original
6666 * (raw) expressions collected by the parse tree. Hence the transformation
6767 * 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.
6885 */
6986Node *
7087transformExpr (ParseState * pstate ,Node * expr ,int precedence )
@@ -254,6 +271,12 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
254271List * qtrees ;
255272Query * qtree ;
256273
274+ /* If we already transformed this node, do nothing */
275+ if (IsA (sublink -> subselect ,Query ))
276+ {
277+ result = expr ;
278+ break ;
279+ }
257280pstate -> p_hasSubLinks = true;
258281qtrees = parse_analyze (lcons (sublink -> subselect ,NIL ),pstate );
259282if (length (qtrees )!= 1 )
@@ -390,7 +413,9 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
390413/*
391414 * It's not shorthand anymore, so drop the implicit
392415 * 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.
394419 */
395420c -> arg = NULL ;
396421
@@ -528,22 +553,14 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
528553break ;
529554}
530555
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+ */
547564case T_Expr :
548565case T_Var :
549566case T_Const :
@@ -555,6 +572,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
555572result = (Node * )expr ;
556573break ;
557574}
575+
558576default :
559577/* should not reach here */
560578elog (ERROR ,"transformExpr: does not know how to transform node %d"