mirror of
https://github.com/postgres/postgres.git
synced 2025-11-09 06:21:09 +03:00
Implement CASE expression.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.33 1998/11/22 10:48:43 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.34 1998/12/04 15:34:05 thomas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -437,7 +437,7 @@ create_nestloop_node(JoinPath *best_path,
|
||||
* used in the inner scan path, so we need only consider the first
|
||||
* set of qualifications in indxqual.
|
||||
*
|
||||
* But there may be more than one clauses in this "first set" in the
|
||||
* But there may be more than one clause in this "first set" in the
|
||||
* case of multi-column indices. - vadim 03/18/97
|
||||
*/
|
||||
|
||||
@@ -735,6 +735,11 @@ fix_indxqual_references(Node *clause, Path *index_path)
|
||||
else
|
||||
return clause;
|
||||
}
|
||||
else if (IsA(clause, CaseExpr))
|
||||
{
|
||||
elog(NOTICE,"optimizer: fix_indxqual_references sees CaseExpr");
|
||||
return clause;
|
||||
}
|
||||
else
|
||||
{
|
||||
List *oldclauses = (List *) clause;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.25 1998/11/27 19:52:07 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.26 1998/12/04 15:34:14 thomas Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@@ -306,6 +306,26 @@ make_andclause(List *andclauses)
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* CASE clause functions
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* case_clause--
|
||||
*
|
||||
* Returns t iff its argument is a 'case' clause: (CASE { expr }).
|
||||
*
|
||||
*/
|
||||
bool
|
||||
case_clause(Node *clause)
|
||||
{
|
||||
return
|
||||
(clause != NULL &&
|
||||
nodeTag(clause) == T_CaseExpr);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* *
|
||||
@@ -540,6 +560,19 @@ fix_opid(Node *clause)
|
||||
fix_opid((Node *) get_leftop((Expr *) lfirst(lst)));
|
||||
}
|
||||
}
|
||||
else if (case_clause(clause))
|
||||
{
|
||||
List *lst;
|
||||
|
||||
fix_opid(((CaseExpr *) clause)->defresult);
|
||||
|
||||
/* Run through the WHEN clauses... */
|
||||
foreach(lst, ((CaseExpr *) clause)->args)
|
||||
{
|
||||
fix_opid(((CaseWhen *) lfirst(lst))->expr);
|
||||
fix_opid(((CaseWhen *) lfirst(lst))->result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -577,13 +610,12 @@ fix_opids(List *clauses)
|
||||
* returned for the value if it is unknown or null.
|
||||
* END OF OLD OBSOLETE COMMENT.
|
||||
* NEW COMMENT:
|
||||
* when defining rules one of the attibutes of the operator can
|
||||
* when defining rules one of the attributes of the operator can
|
||||
* be a Param node (which is supposed to be treated as a constant).
|
||||
* However as there is no value specified for a parameter until run time
|
||||
* this routine used to return "" as value, which made 'compute_selec'
|
||||
* this routine used to return "" as value, which caused 'compute_selec'
|
||||
* to bomb (because it was expecting a lisp integer and got back a lisp
|
||||
* string). Now the code returns a plain old good "lispInteger(0)".
|
||||
*
|
||||
*/
|
||||
void
|
||||
get_relattval(Node *clause,
|
||||
@@ -787,3 +819,4 @@ CommuteClause(Node *clause)
|
||||
lfirst(((Expr *) clause)->args) = lsecond(((Expr *) clause)->args);
|
||||
lsecond(((Expr *) clause)->args) = temp;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.20 1998/09/22 21:48:27 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.21 1998/12/04 15:34:15 thomas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -482,7 +482,6 @@ flatten_tlistentry(Node *tlistentry, List *flat_tlist)
|
||||
flatten_tlistentry(lfirst(elt), flat_tlist));
|
||||
|
||||
return ((Node *) make_funcclause((Func *) expr->oper, temp_result));
|
||||
|
||||
}
|
||||
else if (IsA(tlistentry, Aggreg))
|
||||
{
|
||||
@@ -509,19 +508,36 @@ flatten_tlistentry(Node *tlistentry, List *flat_tlist)
|
||||
|
||||
return tlistentry;
|
||||
}
|
||||
else if (case_clause(tlistentry))
|
||||
{
|
||||
CaseExpr *cexpr = (CaseExpr *) tlistentry;
|
||||
CaseWhen *cwhen;
|
||||
List *elt = NIL;
|
||||
|
||||
foreach(elt, cexpr->args)
|
||||
cwhen = (CaseWhen *)lfirst(elt);
|
||||
cwhen->result = flatten_tlistentry(cwhen->result, flat_tlist);
|
||||
cexpr->defresult = flatten_tlistentry(cexpr->defresult, flat_tlist);
|
||||
|
||||
return ((Node *) cexpr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Expr *expr = (Expr *) tlistentry;
|
||||
|
||||
Var *left = (Var *) flatten_tlistentry((Node *) get_leftop(expr),
|
||||
flat_tlist);
|
||||
Var *right = (Var *) flatten_tlistentry((Node *) get_rightop(expr),
|
||||
flat_tlist);
|
||||
Expr *final = make_opclause((Oper *) expr->oper, left, right);
|
||||
Expr *expr, *final;
|
||||
Var *left, *right;
|
||||
|
||||
Assert(IsA(tlistentry, Expr));
|
||||
|
||||
expr = (Expr *) tlistentry;
|
||||
left = (Var *) flatten_tlistentry((Node *) get_leftop(expr),
|
||||
flat_tlist);
|
||||
right = (Var *) flatten_tlistentry((Node *) get_rightop(expr),
|
||||
flat_tlist);
|
||||
|
||||
final = make_opclause((Oper *) expr->oper, left, right);
|
||||
final->opType = expr->opType;
|
||||
final->typeOid = expr->typeOid;
|
||||
|
||||
return (Node *)final;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.13 1998/09/01 03:24:00 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.14 1998/12/04 15:34:15 thomas Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -137,6 +137,21 @@ contain_var_clause(Node *clause)
|
||||
else if (is_opclause(clause))
|
||||
return (contain_var_clause((Node *) get_leftop((Expr *) clause)) ||
|
||||
contain_var_clause((Node *) get_rightop((Expr *) clause)));
|
||||
else if (case_clause(clause))
|
||||
{
|
||||
List *args;
|
||||
CaseWhen *when;
|
||||
|
||||
foreach(args, ((CaseExpr *) clause)->args)
|
||||
{
|
||||
when = lfirst(args);
|
||||
if (contain_var_clause(when->expr))
|
||||
return TRUE;
|
||||
if (contain_var_clause(when->result))
|
||||
return TRUE;
|
||||
}
|
||||
return (contain_var_clause(((CaseExpr *) clause)->defresult));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -199,6 +214,18 @@ pull_var_clause(Node *clause)
|
||||
else if (is_opclause(clause))
|
||||
retval = nconc(pull_var_clause((Node *) get_leftop((Expr *) clause)),
|
||||
pull_var_clause((Node *) get_rightop((Expr *) clause)));
|
||||
else if (case_clause(clause))
|
||||
{
|
||||
List *temp;
|
||||
|
||||
foreach(temp, ((CaseExpr *) clause)->args)
|
||||
{
|
||||
retval = nconc(retval, pull_var_clause(((CaseWhen *) lfirst(temp))->expr));
|
||||
retval = nconc(retval, pull_var_clause(((CaseWhen *) lfirst(temp))->result));
|
||||
}
|
||||
|
||||
retval = nconc(retval, pull_var_clause(((CaseExpr *) clause)->defresult));
|
||||
}
|
||||
else
|
||||
retval = NIL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user