8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.155 2004/03/17 01:02:23 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.156 2004/03/17 20:48:42 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -81,6 +81,9 @@ static Datum ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
81
81
bool * isNull , ExprDoneCond * isDone );
82
82
static Datum ExecEvalCase (CaseExprState * caseExpr , ExprContext * econtext ,
83
83
bool * isNull , ExprDoneCond * isDone );
84
+ static Datum ExecEvalCaseTestExpr (ExprState * exprstate ,
85
+ ExprContext * econtext ,
86
+ bool * isNull , ExprDoneCond * isDone );
84
87
static Datum ExecEvalArray (ArrayExprState * astate ,
85
88
ExprContext * econtext ,
86
89
bool * isNull , ExprDoneCond * isDone );
@@ -1809,10 +1812,29 @@ ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
1809
1812
{
1810
1813
List * clauses = caseExpr -> args ;
1811
1814
List * clause ;
1815
+ Datum save_datum ;
1816
+ bool save_isNull ;
1812
1817
1813
1818
if (isDone )
1814
1819
* isDone = ExprSingleResult ;
1815
1820
1821
+ /*
1822
+ * If there's a test expression, we have to evaluate it and save
1823
+ * the value where the CaseTestExpr placeholders can find it.
1824
+ * We must save and restore prior setting of econtext's caseValue fields,
1825
+ * in case this node is itself within a larger CASE.
1826
+ */
1827
+ save_datum = econtext -> caseValue_datum ;
1828
+ save_isNull = econtext -> caseValue_isNull ;
1829
+
1830
+ if (caseExpr -> arg )
1831
+ {
1832
+ econtext -> caseValue_datum = ExecEvalExpr (caseExpr -> arg ,
1833
+ econtext ,
1834
+ & econtext -> caseValue_isNull ,
1835
+ NULL );
1836
+ }
1837
+
1816
1838
/*
1817
1839
* we evaluate each of the WHEN clauses in turn, as soon as one is
1818
1840
* true we return the corresponding result. If none are true then we
@@ -1835,13 +1857,18 @@ ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
1835
1857
*/
1836
1858
if (DatumGetBool (clause_value ) && !* isNull )
1837
1859
{
1860
+ econtext -> caseValue_datum = save_datum ;
1861
+ econtext -> caseValue_isNull = save_isNull ;
1838
1862
return ExecEvalExpr (wclause -> result ,
1839
1863
econtext ,
1840
1864
isNull ,
1841
1865
isDone );
1842
1866
}
1843
1867
}
1844
1868
1869
+ econtext -> caseValue_datum = save_datum ;
1870
+ econtext -> caseValue_isNull = save_isNull ;
1871
+
1845
1872
if (caseExpr -> defresult )
1846
1873
{
1847
1874
return ExecEvalExpr (caseExpr -> defresult ,
@@ -1854,6 +1881,22 @@ ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
1854
1881
return (Datum ) 0 ;
1855
1882
}
1856
1883
1884
+ /*
1885
+ * ExecEvalCaseTestExpr
1886
+ *
1887
+ * Return the value stored by CASE.
1888
+ */
1889
+ static Datum
1890
+ ExecEvalCaseTestExpr (ExprState * exprstate ,
1891
+ ExprContext * econtext ,
1892
+ bool * isNull , ExprDoneCond * isDone )
1893
+ {
1894
+ if (isDone )
1895
+ * isDone = ExprSingleResult ;
1896
+ * isNull = econtext -> caseValue_isNull ;
1897
+ return econtext -> caseValue_datum ;
1898
+ }
1899
+
1857
1900
/* ----------------------------------------------------------------
1858
1901
* ExecEvalArray - ARRAY[] expressions
1859
1902
*
@@ -2478,6 +2521,10 @@ ExecInitExpr(Expr *node, PlanState *parent)
2478
2521
state = (ExprState * ) makeNode (ExprState );
2479
2522
state -> evalfunc = ExecEvalCoerceToDomainValue ;
2480
2523
break ;
2524
+ case T_CaseTestExpr :
2525
+ state = (ExprState * ) makeNode (ExprState );
2526
+ state -> evalfunc = ExecEvalCaseTestExpr ;
2527
+ break ;
2481
2528
case T_Aggref :
2482
2529
{
2483
2530
Aggref * aggref = (Aggref * ) node ;
@@ -2666,6 +2713,7 @@ ExecInitExpr(Expr *node, PlanState *parent)
2666
2713
List * inlist ;
2667
2714
2668
2715
cstate -> xprstate .evalfunc = (ExprStateEvalFunc ) ExecEvalCase ;
2716
+ cstate -> arg = ExecInitExpr (caseexpr -> arg , parent );
2669
2717
FastListInit (& outlist );
2670
2718
foreach (inlist , caseexpr -> args )
2671
2719
{
@@ -2680,8 +2728,6 @@ ExecInitExpr(Expr *node, PlanState *parent)
2680
2728
FastAppend (& outlist , wstate );
2681
2729
}
2682
2730
cstate -> args = FastListValue (& outlist );
2683
- /* caseexpr->arg should be null by now */
2684
- Assert (caseexpr -> arg == NULL );
2685
2731
cstate -> defresult = ExecInitExpr (caseexpr -> defresult , parent );
2686
2732
state = (ExprState * ) cstate ;
2687
2733
}
0 commit comments