Pgindent clauses.c, per request from Tom.
This commit is contained in:
parent
a04161f2ea
commit
269755ef72
|
@ -2126,10 +2126,10 @@ eval_const_expressions_mutator(Node *node,
|
||||||
if (context->estimate || (prm->pflags & PARAM_FLAG_CONST))
|
if (context->estimate || (prm->pflags & PARAM_FLAG_CONST))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Return a Const representing the param value. Must copy
|
* Return a Const representing the param value.
|
||||||
* pass-by-ref datatypes, since the Param might be in a
|
* Must copy pass-by-ref datatypes, since the
|
||||||
* memory context shorter-lived than our output plan
|
* Param might be in a memory context
|
||||||
* should be.
|
* shorter-lived than our output plan should be.
|
||||||
*/
|
*/
|
||||||
int16 typLen;
|
int16 typLen;
|
||||||
bool typByVal;
|
bool typByVal;
|
||||||
|
@ -2151,7 +2151,11 @@ eval_const_expressions_mutator(Node *node,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Not replaceable, so just copy the Param (no need to recurse) */
|
|
||||||
|
/*
|
||||||
|
* Not replaceable, so just copy the Param (no need to
|
||||||
|
* recurse)
|
||||||
|
*/
|
||||||
return (Node *) copyObject(param);
|
return (Node *) copyObject(param);
|
||||||
}
|
}
|
||||||
case T_FuncExpr:
|
case T_FuncExpr:
|
||||||
|
@ -2164,8 +2168,8 @@ eval_const_expressions_mutator(Node *node,
|
||||||
ListCell *lc;
|
ListCell *lc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reduce constants in the FuncExpr's arguments, and check to see if
|
* Reduce constants in the FuncExpr's arguments, and check to
|
||||||
* there are any named args.
|
* see if there are any named args.
|
||||||
*/
|
*/
|
||||||
args = NIL;
|
args = NIL;
|
||||||
has_named_args = false;
|
has_named_args = false;
|
||||||
|
@ -2180,10 +2184,11 @@ eval_const_expressions_mutator(Node *node,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code for op/func reduction is pretty bulky, so split it out as a
|
* Code for op/func reduction is pretty bulky, so split it out
|
||||||
* separate function. Note: exprTypmod normally returns -1 for a
|
* as a separate function. Note: exprTypmod normally returns
|
||||||
* FuncExpr, but not when the node is recognizably a length coercion;
|
* -1 for a FuncExpr, but not when the node is recognizably a
|
||||||
* we want to preserve the typmod in the eventual Const if so.
|
* length coercion; we want to preserve the typmod in the
|
||||||
|
* eventual Const if so.
|
||||||
*/
|
*/
|
||||||
simple = simplify_function((Expr *) expr,
|
simple = simplify_function((Expr *) expr,
|
||||||
expr->funcid,
|
expr->funcid,
|
||||||
|
@ -2196,10 +2201,10 @@ eval_const_expressions_mutator(Node *node,
|
||||||
return (Node *) simple;
|
return (Node *) simple;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The expression cannot be simplified any further, so build and
|
* The expression cannot be simplified any further, so build
|
||||||
* return a replacement FuncExpr node using the possibly-simplified
|
* and return a replacement FuncExpr node using the
|
||||||
* arguments. Note that we have also converted the argument list to
|
* possibly-simplified arguments. Note that we have also
|
||||||
* positional notation.
|
* converted the argument list to positional notation.
|
||||||
*/
|
*/
|
||||||
newexpr = makeNode(FuncExpr);
|
newexpr = makeNode(FuncExpr);
|
||||||
newexpr->funcid = expr->funcid;
|
newexpr->funcid = expr->funcid;
|
||||||
|
@ -2220,23 +2225,24 @@ eval_const_expressions_mutator(Node *node,
|
||||||
OpExpr *newexpr;
|
OpExpr *newexpr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reduce constants in the OpExpr's arguments. We know args is either
|
* Reduce constants in the OpExpr's arguments. We know args
|
||||||
* NIL or a List node, so we can call expression_tree_mutator directly
|
* is either NIL or a List node, so we can call
|
||||||
* rather than recursing to self.
|
* expression_tree_mutator directly rather than recursing to
|
||||||
|
* self.
|
||||||
*/
|
*/
|
||||||
args = (List *) expression_tree_mutator((Node *) expr->args,
|
args = (List *) expression_tree_mutator((Node *) expr->args,
|
||||||
eval_const_expressions_mutator,
|
eval_const_expressions_mutator,
|
||||||
(void *) context);
|
(void *) context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Need to get OID of underlying function. Okay to scribble on input
|
* Need to get OID of underlying function. Okay to scribble
|
||||||
* to this extent.
|
* on input to this extent.
|
||||||
*/
|
*/
|
||||||
set_opfuncid(expr);
|
set_opfuncid(expr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code for op/func reduction is pretty bulky, so split it out as a
|
* Code for op/func reduction is pretty bulky, so split it out
|
||||||
* separate function.
|
* as a separate function.
|
||||||
*/
|
*/
|
||||||
simple = simplify_function((Expr *) expr,
|
simple = simplify_function((Expr *) expr,
|
||||||
expr->opfuncid,
|
expr->opfuncid,
|
||||||
|
@ -2249,9 +2255,9 @@ eval_const_expressions_mutator(Node *node,
|
||||||
return (Node *) simple;
|
return (Node *) simple;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the operator is boolean equality or inequality, we know how to
|
* If the operator is boolean equality or inequality, we know
|
||||||
* simplify cases involving one constant and one non-constant
|
* how to simplify cases involving one constant and one
|
||||||
* argument.
|
* non-constant argument.
|
||||||
*/
|
*/
|
||||||
if (expr->opno == BooleanEqualOperator ||
|
if (expr->opno == BooleanEqualOperator ||
|
||||||
expr->opno == BooleanNotEqualOperator)
|
expr->opno == BooleanNotEqualOperator)
|
||||||
|
@ -2262,9 +2268,9 @@ eval_const_expressions_mutator(Node *node,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The expression cannot be simplified any further, so build and
|
* The expression cannot be simplified any further, so build
|
||||||
* return a replacement OpExpr node using the possibly-simplified
|
* and return a replacement OpExpr node using the
|
||||||
* arguments.
|
* possibly-simplified arguments.
|
||||||
*/
|
*/
|
||||||
newexpr = makeNode(OpExpr);
|
newexpr = makeNode(OpExpr);
|
||||||
newexpr->opno = expr->opno;
|
newexpr->opno = expr->opno;
|
||||||
|
@ -2289,9 +2295,10 @@ eval_const_expressions_mutator(Node *node,
|
||||||
DistinctExpr *newexpr;
|
DistinctExpr *newexpr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reduce constants in the DistinctExpr's arguments. We know args is
|
* Reduce constants in the DistinctExpr's arguments. We know
|
||||||
* either NIL or a List node, so we can call expression_tree_mutator
|
* args is either NIL or a List node, so we can call
|
||||||
* directly rather than recursing to self.
|
* expression_tree_mutator directly rather than recursing to
|
||||||
|
* self.
|
||||||
*/
|
*/
|
||||||
args = (List *) expression_tree_mutator((Node *) expr->args,
|
args = (List *) expression_tree_mutator((Node *) expr->args,
|
||||||
eval_const_expressions_mutator,
|
eval_const_expressions_mutator,
|
||||||
|
@ -2299,7 +2306,8 @@ eval_const_expressions_mutator(Node *node,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must do our own check for NULLs because DistinctExpr has
|
* We must do our own check for NULLs because DistinctExpr has
|
||||||
* different results for NULL input than the underlying operator does.
|
* different results for NULL input than the underlying
|
||||||
|
* operator does.
|
||||||
*/
|
*/
|
||||||
foreach(arg, args)
|
foreach(arg, args)
|
||||||
{
|
{
|
||||||
|
@ -2327,14 +2335,15 @@ eval_const_expressions_mutator(Node *node,
|
||||||
/* (NOT okay to try to inline it, though!) */
|
/* (NOT okay to try to inline it, though!) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Need to get OID of underlying function. Okay to scribble on
|
* Need to get OID of underlying function. Okay to
|
||||||
* input to this extent.
|
* scribble on input to this extent.
|
||||||
*/
|
*/
|
||||||
set_opfuncid((OpExpr *) expr); /* rely on struct equivalence */
|
set_opfuncid((OpExpr *) expr); /* rely on struct
|
||||||
|
* equivalence */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code for op/func reduction is pretty bulky, so split it out as
|
* Code for op/func reduction is pretty bulky, so split it
|
||||||
* a separate function.
|
* out as a separate function.
|
||||||
*/
|
*/
|
||||||
simple = simplify_function((Expr *) expr,
|
simple = simplify_function((Expr *) expr,
|
||||||
expr->opfuncid,
|
expr->opfuncid,
|
||||||
|
@ -2346,8 +2355,8 @@ eval_const_expressions_mutator(Node *node,
|
||||||
if (simple) /* successfully simplified it */
|
if (simple) /* successfully simplified it */
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Since the underlying operator is "=", must negate its
|
* Since the underlying operator is "=", must negate
|
||||||
* result
|
* its result
|
||||||
*/
|
*/
|
||||||
Const *csimple = (Const *) simple;
|
Const *csimple = (Const *) simple;
|
||||||
|
|
||||||
|
@ -2359,8 +2368,8 @@ eval_const_expressions_mutator(Node *node,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The expression cannot be simplified any further, so build and
|
* The expression cannot be simplified any further, so build
|
||||||
* return a replacement DistinctExpr node using the
|
* and return a replacement DistinctExpr node using the
|
||||||
* possibly-simplified arguments.
|
* possibly-simplified arguments.
|
||||||
*/
|
*/
|
||||||
newexpr = makeNode(DistinctExpr);
|
newexpr = makeNode(DistinctExpr);
|
||||||
|
@ -2395,7 +2404,11 @@ eval_const_expressions_mutator(Node *node,
|
||||||
/* If all the inputs are FALSE, result is FALSE */
|
/* If all the inputs are FALSE, result is FALSE */
|
||||||
if (newargs == NIL)
|
if (newargs == NIL)
|
||||||
return makeBoolConst(false, false);
|
return makeBoolConst(false, false);
|
||||||
/* If only one nonconst-or-NULL input, it's the result */
|
|
||||||
|
/*
|
||||||
|
* If only one nonconst-or-NULL input, it's the
|
||||||
|
* result
|
||||||
|
*/
|
||||||
if (list_length(newargs) == 1)
|
if (list_length(newargs) == 1)
|
||||||
return (Node *) linitial(newargs);
|
return (Node *) linitial(newargs);
|
||||||
/* Else we still need an OR node */
|
/* Else we still need an OR node */
|
||||||
|
@ -2416,7 +2429,11 @@ eval_const_expressions_mutator(Node *node,
|
||||||
/* If all the inputs are TRUE, result is TRUE */
|
/* If all the inputs are TRUE, result is TRUE */
|
||||||
if (newargs == NIL)
|
if (newargs == NIL)
|
||||||
return makeBoolConst(true, false);
|
return makeBoolConst(true, false);
|
||||||
/* If only one nonconst-or-NULL input, it's the result */
|
|
||||||
|
/*
|
||||||
|
* If only one nonconst-or-NULL input, it's the
|
||||||
|
* result
|
||||||
|
*/
|
||||||
if (list_length(newargs) == 1)
|
if (list_length(newargs) == 1)
|
||||||
return (Node *) linitial(newargs);
|
return (Node *) linitial(newargs);
|
||||||
/* Else we still need an AND node */
|
/* Else we still need an AND node */
|
||||||
|
@ -2431,8 +2448,8 @@ eval_const_expressions_mutator(Node *node,
|
||||||
context);
|
context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use negate_clause() to see if we can simplify away the
|
* Use negate_clause() to see if we can simplify
|
||||||
* NOT.
|
* away the NOT.
|
||||||
*/
|
*/
|
||||||
return negate_clause(arg);
|
return negate_clause(arg);
|
||||||
}
|
}
|
||||||
|
@ -2445,19 +2462,21 @@ eval_const_expressions_mutator(Node *node,
|
||||||
}
|
}
|
||||||
case T_SubPlan:
|
case T_SubPlan:
|
||||||
case T_AlternativeSubPlan:
|
case T_AlternativeSubPlan:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a SubPlan unchanged --- too late to do anything with it.
|
* Return a SubPlan unchanged --- too late to do anything with it.
|
||||||
*
|
*
|
||||||
* XXX should we ereport() here instead? Probably this routine should
|
* XXX should we ereport() here instead? Probably this routine
|
||||||
* never be invoked after SubPlan creation.
|
* should never be invoked after SubPlan creation.
|
||||||
*/
|
*/
|
||||||
return node;
|
return node;
|
||||||
case T_RelabelType:
|
case T_RelabelType:
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If we can simplify the input to a constant, then we don't need the
|
* If we can simplify the input to a constant, then we don't
|
||||||
* RelabelType node anymore: just change the type field of the Const
|
* need the RelabelType node anymore: just change the type
|
||||||
* node. Otherwise, must copy the RelabelType node.
|
* field of the Const node. Otherwise, must copy the
|
||||||
|
* RelabelType node.
|
||||||
*/
|
*/
|
||||||
RelabelType *relabel = (RelabelType *) node;
|
RelabelType *relabel = (RelabelType *) node;
|
||||||
Node *arg;
|
Node *arg;
|
||||||
|
@ -2466,8 +2485,8 @@ eval_const_expressions_mutator(Node *node,
|
||||||
context);
|
context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we find stacked RelabelTypes (eg, from foo :: int :: oid) we can
|
* If we find stacked RelabelTypes (eg, from foo :: int ::
|
||||||
* discard all but the top one.
|
* oid) we can discard all but the top one.
|
||||||
*/
|
*/
|
||||||
while (arg && IsA(arg, RelabelType))
|
while (arg && IsA(arg, RelabelType))
|
||||||
arg = (Node *) ((RelabelType *) arg)->arg;
|
arg = (Node *) ((RelabelType *) arg)->arg;
|
||||||
|
@ -2514,13 +2533,13 @@ eval_const_expressions_mutator(Node *node,
|
||||||
args = list_make1(arg);
|
args = list_make1(arg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CoerceViaIO represents calling the source type's output function
|
* CoerceViaIO represents calling the source type's output
|
||||||
* then the result type's input function. So, try to simplify it as
|
* function then the result type's input function. So, try to
|
||||||
* though it were a stack of two such function calls. First we need
|
* simplify it as though it were a stack of two such function
|
||||||
* to know what the functions are.
|
* calls. First we need to know what the functions are.
|
||||||
*
|
*
|
||||||
* Note that the coercion functions are assumed not to care about
|
* Note that the coercion functions are assumed not to care
|
||||||
* input collation, so we just pass InvalidOid for that.
|
* about input collation, so we just pass InvalidOid for that.
|
||||||
*/
|
*/
|
||||||
getTypeOutputInfo(exprType((Node *) arg), &outfunc, &outtypisvarlena);
|
getTypeOutputInfo(exprType((Node *) arg), &outfunc, &outtypisvarlena);
|
||||||
getTypeInputInfo(expr->resulttype, &infunc, &intypioparam);
|
getTypeInputInfo(expr->resulttype, &infunc, &intypioparam);
|
||||||
|
@ -2535,8 +2554,9 @@ eval_const_expressions_mutator(Node *node,
|
||||||
if (simple) /* successfully simplified output fn */
|
if (simple) /* successfully simplified output fn */
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Input functions may want 1 to 3 arguments. We always supply
|
* Input functions may want 1 to 3 arguments. We always
|
||||||
* all three, trusting that nothing downstream will complain.
|
* supply all three, trusting that nothing downstream will
|
||||||
|
* complain.
|
||||||
*/
|
*/
|
||||||
args = list_make3(simple,
|
args = list_make3(simple,
|
||||||
makeConst(OIDOID, -1, InvalidOid, sizeof(Oid),
|
makeConst(OIDOID, -1, InvalidOid, sizeof(Oid),
|
||||||
|
@ -2558,9 +2578,9 @@ eval_const_expressions_mutator(Node *node,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The expression cannot be simplified any further, so build and
|
* The expression cannot be simplified any further, so build
|
||||||
* return a replacement CoerceViaIO node using the possibly-simplified
|
* and return a replacement CoerceViaIO node using the
|
||||||
* argument.
|
* possibly-simplified argument.
|
||||||
*/
|
*/
|
||||||
newexpr = makeNode(CoerceViaIO);
|
newexpr = makeNode(CoerceViaIO);
|
||||||
newexpr->arg = arg;
|
newexpr->arg = arg;
|
||||||
|
@ -2577,8 +2597,8 @@ eval_const_expressions_mutator(Node *node,
|
||||||
ArrayCoerceExpr *newexpr;
|
ArrayCoerceExpr *newexpr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reduce constants in the ArrayCoerceExpr's argument, then build a
|
* Reduce constants in the ArrayCoerceExpr's argument, then
|
||||||
* new ArrayCoerceExpr.
|
* build a new ArrayCoerceExpr.
|
||||||
*/
|
*/
|
||||||
arg = (Expr *) eval_const_expressions_mutator((Node *) expr->arg,
|
arg = (Expr *) eval_const_expressions_mutator((Node *) expr->arg,
|
||||||
context);
|
context);
|
||||||
|
@ -2594,8 +2614,8 @@ eval_const_expressions_mutator(Node *node,
|
||||||
newexpr->location = expr->location;
|
newexpr->location = expr->location;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If constant argument and it's a binary-coercible or immutable
|
* If constant argument and it's a binary-coercible or
|
||||||
* conversion, we can simplify it to a constant.
|
* immutable conversion, we can simplify it to a constant.
|
||||||
*/
|
*/
|
||||||
if (arg && IsA(arg, Const) &&
|
if (arg && IsA(arg, Const) &&
|
||||||
(!OidIsValid(newexpr->elemfuncid) ||
|
(!OidIsValid(newexpr->elemfuncid) ||
|
||||||
|
@ -2611,11 +2631,12 @@ eval_const_expressions_mutator(Node *node,
|
||||||
case T_CollateExpr:
|
case T_CollateExpr:
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If we can simplify the input to a constant, then we don't need the
|
* If we can simplify the input to a constant, then we don't
|
||||||
* CollateExpr node at all: just change the constcollid field of the
|
* need the CollateExpr node at all: just change the
|
||||||
* Const node. Otherwise, replace the CollateExpr with a RelabelType.
|
* constcollid field of the Const node. Otherwise, replace
|
||||||
* (We do that so as to improve uniformity of expression
|
* the CollateExpr with a RelabelType. (We do that so as to
|
||||||
* representation and thus simplify comparison of expressions.)
|
* improve uniformity of expression representation and thus
|
||||||
|
* simplify comparison of expressions.)
|
||||||
*/
|
*/
|
||||||
CollateExpr *collate = (CollateExpr *) node;
|
CollateExpr *collate = (CollateExpr *) node;
|
||||||
Node *arg;
|
Node *arg;
|
||||||
|
@ -2702,7 +2723,8 @@ eval_const_expressions_mutator(Node *node,
|
||||||
if (newarg && IsA(newarg, Const))
|
if (newarg && IsA(newarg, Const))
|
||||||
{
|
{
|
||||||
context->case_val = newarg;
|
context->case_val = newarg;
|
||||||
newarg = NULL; /* not needed anymore, see comment above */
|
newarg = NULL; /* not needed anymore, see comment
|
||||||
|
* above */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context->case_val = NULL;
|
context->case_val = NULL;
|
||||||
|
@ -2724,8 +2746,9 @@ eval_const_expressions_mutator(Node *node,
|
||||||
context);
|
context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the test condition is constant FALSE (or NULL), then drop
|
* If the test condition is constant FALSE (or NULL), then
|
||||||
* this WHEN clause completely, without processing the result.
|
* drop this WHEN clause completely, without processing
|
||||||
|
* the result.
|
||||||
*/
|
*/
|
||||||
if (casecond && IsA(casecond, Const))
|
if (casecond && IsA(casecond, Const))
|
||||||
{
|
{
|
||||||
|
@ -2733,7 +2756,8 @@ eval_const_expressions_mutator(Node *node,
|
||||||
|
|
||||||
if (const_input->constisnull ||
|
if (const_input->constisnull ||
|
||||||
!DatumGetBool(const_input->constvalue))
|
!DatumGetBool(const_input->constvalue))
|
||||||
continue; /* drop alternative with FALSE condition */
|
continue; /* drop alternative with FALSE
|
||||||
|
* condition */
|
||||||
/* Else it's constant TRUE */
|
/* Else it's constant TRUE */
|
||||||
const_true_cond = true;
|
const_true_cond = true;
|
||||||
}
|
}
|
||||||
|
@ -2756,8 +2780,9 @@ eval_const_expressions_mutator(Node *node,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Found a TRUE condition, so none of the remaining alternatives
|
* Found a TRUE condition, so none of the remaining
|
||||||
* can be reached. We treat the result as the default result.
|
* alternatives can be reached. We treat the result as
|
||||||
|
* the default result.
|
||||||
*/
|
*/
|
||||||
defresult = caseresult;
|
defresult = caseresult;
|
||||||
break;
|
break;
|
||||||
|
@ -2771,7 +2796,10 @@ eval_const_expressions_mutator(Node *node,
|
||||||
|
|
||||||
context->case_val = save_case_val;
|
context->case_val = save_case_val;
|
||||||
|
|
||||||
/* If no non-FALSE alternatives, CASE reduces to the default result */
|
/*
|
||||||
|
* If no non-FALSE alternatives, CASE reduces to the default
|
||||||
|
* result
|
||||||
|
*/
|
||||||
if (newargs == NIL)
|
if (newargs == NIL)
|
||||||
return defresult;
|
return defresult;
|
||||||
/* Otherwise we need a new CASE node */
|
/* Otherwise we need a new CASE node */
|
||||||
|
@ -2787,9 +2815,9 @@ eval_const_expressions_mutator(Node *node,
|
||||||
case T_CaseTestExpr:
|
case T_CaseTestExpr:
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If we know a constant test value for the current CASE construct,
|
* If we know a constant test value for the current CASE
|
||||||
* substitute it for the placeholder. Else just return the
|
* construct, substitute it for the placeholder. Else just
|
||||||
* placeholder as-is.
|
* return the placeholder as-is.
|
||||||
*/
|
*/
|
||||||
if (context->case_val)
|
if (context->case_val)
|
||||||
return copyObject(context->case_val);
|
return copyObject(context->case_val);
|
||||||
|
@ -2848,11 +2876,12 @@ eval_const_expressions_mutator(Node *node,
|
||||||
context);
|
context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can remove null constants from the list. For a non-null
|
* We can remove null constants from the list. For a
|
||||||
* constant, if it has not been preceded by any other
|
* non-null constant, if it has not been preceded by any
|
||||||
* non-null-constant expressions then it is the result. Otherwise,
|
* other non-null-constant expressions then it is the
|
||||||
* it's the next argument, but we can drop following arguments
|
* result. Otherwise, it's the next argument, but we can
|
||||||
* since they will never be reached.
|
* drop following arguments since they will never be
|
||||||
|
* reached.
|
||||||
*/
|
*/
|
||||||
if (IsA(e, Const))
|
if (IsA(e, Const))
|
||||||
{
|
{
|
||||||
|
@ -2866,7 +2895,10 @@ eval_const_expressions_mutator(Node *node,
|
||||||
newargs = lappend(newargs, e);
|
newargs = lappend(newargs, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If all the arguments were constant null, the result is just null */
|
/*
|
||||||
|
* If all the arguments were constant null, the result is just
|
||||||
|
* null
|
||||||
|
*/
|
||||||
if (newargs == NIL)
|
if (newargs == NIL)
|
||||||
return (Node *) makeNullConst(coalesceexpr->coalescetype,
|
return (Node *) makeNullConst(coalesceexpr->coalescetype,
|
||||||
-1,
|
-1,
|
||||||
|
@ -2882,15 +2914,16 @@ eval_const_expressions_mutator(Node *node,
|
||||||
case T_FieldSelect:
|
case T_FieldSelect:
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We can optimize field selection from a whole-row Var into a simple
|
* We can optimize field selection from a whole-row Var into a
|
||||||
* Var. (This case won't be generated directly by the parser, because
|
* simple Var. (This case won't be generated directly by the
|
||||||
* ParseComplexProjection short-circuits it. But it can arise while
|
* parser, because ParseComplexProjection short-circuits it.
|
||||||
* simplifying functions.) Also, we can optimize field selection from
|
* But it can arise while simplifying functions.) Also, we
|
||||||
* a RowExpr construct.
|
* can optimize field selection from a RowExpr construct.
|
||||||
*
|
*
|
||||||
* We must however check that the declared type of the field is still
|
* We must however check that the declared type of the field
|
||||||
* the same as when the FieldSelect was created --- this can change if
|
* is still the same as when the FieldSelect was created ---
|
||||||
* someone did ALTER COLUMN TYPE on the rowtype.
|
* this can change if someone did ALTER COLUMN TYPE on the
|
||||||
|
* rowtype.
|
||||||
*/
|
*/
|
||||||
FieldSelect *fselect = (FieldSelect *) node;
|
FieldSelect *fselect = (FieldSelect *) node;
|
||||||
FieldSelect *newfselect;
|
FieldSelect *newfselect;
|
||||||
|
@ -2953,9 +2986,10 @@ eval_const_expressions_mutator(Node *node,
|
||||||
if (arg && IsA(arg, RowExpr))
|
if (arg && IsA(arg, RowExpr))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We break ROW(...) IS [NOT] NULL into separate tests on its
|
* We break ROW(...) IS [NOT] NULL into separate tests on
|
||||||
* component fields. This form is usually more efficient to
|
* its component fields. This form is usually more
|
||||||
* evaluate, as well as being more amenable to optimization.
|
* efficient to evaluate, as well as being more amenable
|
||||||
|
* to optimization.
|
||||||
*/
|
*/
|
||||||
RowExpr *rarg = (RowExpr *) arg;
|
RowExpr *rarg = (RowExpr *) arg;
|
||||||
List *newargs = NIL;
|
List *newargs = NIL;
|
||||||
|
@ -2968,8 +3002,8 @@ eval_const_expressions_mutator(Node *node,
|
||||||
Node *relem = (Node *) lfirst(l);
|
Node *relem = (Node *) lfirst(l);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A constant field refutes the whole NullTest if it's of the
|
* A constant field refutes the whole NullTest if it's
|
||||||
* wrong nullness; else we can discard it.
|
* of the wrong nullness; else we can discard it.
|
||||||
*/
|
*/
|
||||||
if (relem && IsA(relem, Const))
|
if (relem && IsA(relem, Const))
|
||||||
{
|
{
|
||||||
|
@ -3078,12 +3112,13 @@ eval_const_expressions_mutator(Node *node,
|
||||||
return (Node *) newbtest;
|
return (Node *) newbtest;
|
||||||
}
|
}
|
||||||
case T_PlaceHolderVar:
|
case T_PlaceHolderVar:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In estimation mode, just strip the PlaceHolderVar node altogether;
|
* In estimation mode, just strip the PlaceHolderVar node
|
||||||
* this amounts to estimating that the contained value won't be forced
|
* altogether; this amounts to estimating that the contained value
|
||||||
* to null by an outer join. In regular mode we just use the default
|
* won't be forced to null by an outer join. In regular mode we
|
||||||
* behavior (ie, simplify the expression but leave the PlaceHolderVar
|
* just use the default behavior (ie, simplify the expression but
|
||||||
* node intact).
|
* leave the PlaceHolderVar node intact).
|
||||||
*/
|
*/
|
||||||
if (context->estimate)
|
if (context->estimate)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue