1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-16 15:02:33 +03:00

Reimplement CASE val WHEN compval1 THEN ... WHEN compval2 THEN ... END

so that the 'val' is computed only once, per recent discussion.  The
speedup is not much when 'val' is just a simple variable, but could be
significant for larger expressions.  More importantly this avoids issues
with multiple evaluations of a volatile 'val', and it allows the CASE
expression to be reverse-listed in its original form by ruleutils.c.
This commit is contained in:
Tom Lane
2004-03-17 20:48:43 +00:00
parent 8c702ea7ac
commit 55f7c3300d
16 changed files with 248 additions and 55 deletions

View File

@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.95 2004/03/14 23:41:27 tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.96 2004/03/17 20:48:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -563,8 +563,27 @@ typedef struct RelabelType
CoercionForm relabelformat; /* how to display this node */
} RelabelType;
/*
/*----------
* CaseExpr - a CASE expression
*
* We support two distinct forms of CASE expression:
* CASE WHEN boolexpr THEN expr [ WHEN boolexpr THEN expr ... ]
* CASE testexpr WHEN compexpr THEN expr [ WHEN compexpr THEN expr ... ]
* These are distinguishable by the "arg" field being NULL in the first case
* and the testexpr in the second case.
*
* In the raw grammar output for the second form, the condition expressions
* of the WHEN clauses are just the comparison values. Parse analysis
* converts these to valid boolean expressions of the form
* CaseTestExpr '=' compexpr
* where the CaseTestExpr node is a placeholder that emits the correct
* value at runtime. This structure is used so that the testexpr need be
* evaluated only once. Note that after parse analysis, the condition
* expressions always yield boolean.
*
* Note: we can test whether a CaseExpr has been through parse analysis
* yet by checking whether casetype is InvalidOid or not.
*----------
*/
typedef struct CaseExpr
{
@@ -576,7 +595,7 @@ typedef struct CaseExpr
} CaseExpr;
/*
* CaseWhen - an argument to a CASE expression
* CaseWhen - one arm of a CASE expression
*/
typedef struct CaseWhen
{
@@ -585,6 +604,18 @@ typedef struct CaseWhen
Expr *result; /* substitution result */
} CaseWhen;
/*
* Placeholder node for the test value to be processed by a CASE expression.
* This is effectively like a Param, but can be implemented more simply
* since we need only one replacement value at a time.
*/
typedef struct CaseTestExpr
{
Expr xpr;
Oid typeId; /* type for substituted value */
int32 typeMod; /* typemod for substituted value */
} CaseTestExpr;
/*
* ArrayExpr - an ARRAY[] expression
*