88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.102 2001/09/28 08:09:09 thomas Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.103 2001/10/08 21:46:59 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -426,15 +426,23 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
426426case T_CaseExpr :
427427{
428428CaseExpr * c = (CaseExpr * )expr ;
429- CaseWhen * w ;
429+ CaseExpr * newc = makeNode (CaseExpr );
430+ List * newargs = NIL ;
430431List * typeids = NIL ;
431432List * args ;
433+ Node * defresult ;
432434Oid ptype ;
433435
434436/* transform the list of arguments */
435437foreach (args ,c -> args )
436438{
437- w = lfirst (args );
439+ CaseWhen * w = (CaseWhen * )lfirst (args );
440+ CaseWhen * neww = makeNode (CaseWhen );
441+ Node * warg ;
442+
443+ Assert (IsA (w ,CaseWhen ));
444+
445+ warg = w -> expr ;
438446if (c -> arg != NULL )
439447{
440448/* shorthand form was specified, so expand... */
@@ -443,81 +451,81 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
443451a -> oper = OP ;
444452a -> opname = "=" ;
445453a -> lexpr = c -> arg ;
446- a -> rexpr = w -> expr ;
447- w -> expr = (Node * )a ;
454+ a -> rexpr = warg ;
455+ warg = (Node * )a ;
448456}
449- lfirst (args )= transformExpr (pstate , (Node * )w ,precedence );
450- typeids = lappendi (typeids ,exprType (w -> result ));
457+ neww -> expr = transformExpr (pstate ,warg ,precedence );
458+
459+ if (!coerce_to_boolean (pstate ,& neww -> expr ))
460+ elog (ERROR ,"WHEN clause must have a boolean result" );
461+
462+ /*
463+ * result is NULL for NULLIF() construct - thomas
464+ * 1998-11-11
465+ */
466+ warg = w -> result ;
467+ if (warg == NULL )
468+ {
469+ A_Const * n = makeNode (A_Const );
470+
471+ n -> val .type = T_Null ;
472+ warg = (Node * )n ;
473+ }
474+ neww -> result = transformExpr (pstate ,warg ,precedence );
475+
476+ newargs = lappend (newargs ,neww );
477+ typeids = lappendi (typeids ,exprType (neww -> result ));
451478}
452479
480+ newc -> args = newargs ;
481+
453482/*
454483 * It's not shorthand anymore, so drop the implicit
455- * argument. This is necessary to keep the executor from
456- * seeing an untransformed expression... not to mention
457- * keeping a re-application of transformExpr from doing
458- * the wrong thing.
484+ * argument. This is necessary to keep any re-application
485+ * of transformExpr from doing the wrong thing.
459486 */
460- c -> arg = NULL ;
487+ newc -> arg = NULL ;
461488
462489/* transform the default clause */
463- if (c -> defresult == NULL )
490+ defresult = c -> defresult ;
491+ if (defresult == NULL )
464492{
465493A_Const * n = makeNode (A_Const );
466494
467495n -> val .type = T_Null ;
468- c -> defresult = (Node * )n ;
496+ defresult = (Node * )n ;
469497}
470- c -> defresult = transformExpr (pstate ,c -> defresult ,precedence );
498+ newc -> defresult = transformExpr (pstate ,defresult ,precedence );
471499
472500/*
473501 * Note: default result is considered the most significant
474502 * type in determining preferred type.This is how the
475503 * code worked before, but it seems a little bogus to me
476504 * --- tgl
477505 */
478- typeids = lconsi (exprType (c -> defresult ),typeids );
506+ typeids = lconsi (exprType (newc -> defresult ),typeids );
479507
480508ptype = select_common_type (typeids ,"CASE" );
481- c -> casetype = ptype ;
509+ newc -> casetype = ptype ;
482510
483511/* Convert default result clause, if necessary */
484- c -> defresult = coerce_to_common_type (pstate ,c -> defresult ,
485- ptype ,"CASE/ELSE" );
512+ newc -> defresult = coerce_to_common_type (pstate ,
513+ newc -> defresult ,
514+ ptype ,
515+ "CASE/ELSE" );
486516
487517/* Convert when-clause results, if necessary */
488- foreach (args ,c -> args )
489- {
490- w = lfirst (args );
491- w -> result = coerce_to_common_type (pstate ,w -> result ,
492- ptype ,"CASE/WHEN" );
493- }
494-
495- result = expr ;
496- break ;
497- }
498-
499- case T_CaseWhen :
500- {
501- CaseWhen * w = (CaseWhen * )expr ;
502-
503- w -> expr = transformExpr (pstate ,w -> expr ,precedence );
504-
505- if (!coerce_to_boolean (pstate ,& w -> expr ))
506- elog (ERROR ,"WHEN clause must have a boolean result" );
507-
508- /*
509- * result is NULL for NULLIF() construct - thomas
510- * 1998-11-11
511- */
512- if (w -> result == NULL )
518+ foreach (args ,newc -> args )
513519{
514- A_Const * n = makeNode ( A_Const );
520+ CaseWhen * w = ( CaseWhen * ) lfirst ( args );
515521
516- n -> val .type = T_Null ;
517- w -> result = (Node * )n ;
522+ w -> result = coerce_to_common_type (pstate ,
523+ w -> result ,
524+ ptype ,
525+ "CASE/WHEN" );
518526}
519- w -> result = transformExpr ( pstate , w -> result , precedence );
520- result = expr ;
527+
528+ result = ( Node * ) newc ;
521529break ;
522530}
523531