mirror of
https://github.com/postgres/postgres.git
synced 2025-11-06 07:49:08 +03:00
Standard pgindent run for 8.1.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.200 2005/07/03 21:14:17 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.201 2005/10/15 02:49:21 momjian Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@@ -91,7 +91,7 @@ static Expr *inline_function(Oid funcid, Oid result_type, List *args,
|
||||
static Node *substitute_actual_parameters(Node *expr, int nargs, List *args,
|
||||
int *usecounts);
|
||||
static Node *substitute_actual_parameters_mutator(Node *node,
|
||||
substitute_actual_parameters_context *context);
|
||||
substitute_actual_parameters_context *context);
|
||||
static void sql_inline_error_callback(void *arg);
|
||||
static Expr *evaluate_expr(Expr *expr, Oid result_type);
|
||||
|
||||
@@ -308,10 +308,10 @@ List *
|
||||
make_ands_implicit(Expr *clause)
|
||||
{
|
||||
/*
|
||||
* NB: because the parser sets the qual field to NULL in a query that
|
||||
* has no WHERE clause, we must consider a NULL input clause as TRUE,
|
||||
* even though one might more reasonably think it FALSE. Grumble. If
|
||||
* this causes trouble, consider changing the parser's behavior.
|
||||
* NB: because the parser sets the qual field to NULL in a query that has
|
||||
* no WHERE clause, we must consider a NULL input clause as TRUE, even
|
||||
* though one might more reasonably think it FALSE. Grumble. If this
|
||||
* causes trouble, consider changing the parser's behavior.
|
||||
*/
|
||||
if (clause == NULL)
|
||||
return NIL; /* NULL -> NIL list == TRUE */
|
||||
@@ -357,8 +357,7 @@ contain_agg_clause_walker(Node *node, void *context)
|
||||
if (IsA(node, Aggref))
|
||||
{
|
||||
Assert(((Aggref *) node)->agglevelsup == 0);
|
||||
return true; /* abort the tree traversal and return
|
||||
* true */
|
||||
return true; /* abort the tree traversal and return true */
|
||||
}
|
||||
Assert(!IsA(node, SubLink));
|
||||
return expression_tree_walker(node, contain_agg_clause_walker, context);
|
||||
@@ -438,9 +437,9 @@ count_agg_clauses_walker(Node *node, AggClauseCounts *counts)
|
||||
|
||||
/*
|
||||
* If the transition type is pass-by-value then it doesn't add
|
||||
* anything to the required size of the hashtable. If it is
|
||||
* pass-by-reference then we have to add the estimated size of
|
||||
* the value itself, plus palloc overhead.
|
||||
* anything to the required size of the hashtable. If it is
|
||||
* pass-by-reference then we have to add the estimated size of the
|
||||
* value itself, plus palloc overhead.
|
||||
*/
|
||||
if (!get_typbyval(aggtranstype))
|
||||
{
|
||||
@@ -470,7 +469,7 @@ count_agg_clauses_walker(Node *node, AggClauseCounts *counts)
|
||||
if (contain_agg_clause((Node *) aggref->target))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_GROUPING_ERROR),
|
||||
errmsg("aggregate function calls may not be nested")));
|
||||
errmsg("aggregate function calls may not be nested")));
|
||||
|
||||
/*
|
||||
* Having checked that, we need not recurse into the argument.
|
||||
@@ -579,8 +578,7 @@ contain_subplans_walker(Node *node, void *context)
|
||||
return false;
|
||||
if (IsA(node, SubPlan) ||
|
||||
IsA(node, SubLink))
|
||||
return true; /* abort the tree traversal and return
|
||||
* true */
|
||||
return true; /* abort the tree traversal and return true */
|
||||
return expression_tree_walker(node, contain_subplans_walker, context);
|
||||
}
|
||||
|
||||
@@ -882,9 +880,9 @@ is_pseudo_constant_clause(Node *clause)
|
||||
{
|
||||
/*
|
||||
* We could implement this check in one recursive scan. But since the
|
||||
* check for volatile functions is both moderately expensive and
|
||||
* unlikely to fail, it seems better to look for Vars first and only
|
||||
* check for volatile functions if we find no Vars.
|
||||
* check for volatile functions is both moderately expensive and unlikely
|
||||
* to fail, it seems better to look for Vars first and only check for
|
||||
* volatile functions if we find no Vars.
|
||||
*/
|
||||
if (!contain_var_clause(clause) &&
|
||||
!contain_volatile_functions(clause))
|
||||
@@ -958,13 +956,12 @@ has_distinct_on_clause(Query *query)
|
||||
|
||||
/*
|
||||
* If the DISTINCT list contains all the nonjunk targetlist items, and
|
||||
* nothing else (ie, no junk tlist items), then it's a simple
|
||||
* DISTINCT, else it's DISTINCT ON. We do not require the lists to be
|
||||
* in the same order (since the parser may have adjusted the DISTINCT
|
||||
* clause ordering to agree with ORDER BY). Furthermore, a
|
||||
* non-DISTINCT junk tlist item that is in the sortClause is also
|
||||
* evidence of DISTINCT ON, since we don't allow ORDER BY on junk
|
||||
* tlist items when plain DISTINCT is used.
|
||||
* nothing else (ie, no junk tlist items), then it's a simple DISTINCT,
|
||||
* else it's DISTINCT ON. We do not require the lists to be in the same
|
||||
* order (since the parser may have adjusted the DISTINCT clause ordering
|
||||
* to agree with ORDER BY). Furthermore, a non-DISTINCT junk tlist item
|
||||
* that is in the sortClause is also evidence of DISTINCT ON, since we
|
||||
* don't allow ORDER BY on junk tlist items when plain DISTINCT is used.
|
||||
*
|
||||
* This code assumes that the DISTINCT list is valid, ie, all its entries
|
||||
* match some entry of the tlist.
|
||||
@@ -1224,7 +1221,7 @@ eval_const_expressions(Node *node)
|
||||
*
|
||||
* Currently the extra steps that are taken in this mode are:
|
||||
* 1. Substitute values for Params, where a bound Param value has been made
|
||||
* available by the caller of planner().
|
||||
* available by the caller of planner().
|
||||
* 2. Fold stable, as well as immutable, functions to constants.
|
||||
*--------------------
|
||||
*/
|
||||
@@ -1264,11 +1261,11 @@ eval_const_expressions_mutator(Node *node,
|
||||
if (paramInfo)
|
||||
{
|
||||
/*
|
||||
* Found it, so return a Const representing the param
|
||||
* value. Note that we don't copy pass-by-ref datatypes,
|
||||
* so the Const will only be valid as long as the bound
|
||||
* parameter list exists. This is okay for intended uses
|
||||
* of estimate_expression_value().
|
||||
* Found it, so return a Const representing the param value.
|
||||
* Note that we don't copy pass-by-ref datatypes, so the Const
|
||||
* will only be valid as long as the bound parameter list
|
||||
* exists. This is okay for intended uses of
|
||||
* estimate_expression_value().
|
||||
*/
|
||||
int16 typLen;
|
||||
bool typByVal;
|
||||
@@ -1294,16 +1291,16 @@ eval_const_expressions_mutator(Node *node,
|
||||
|
||||
/*
|
||||
* Reduce constants in the FuncExpr's arguments. We know args is
|
||||
* either NIL or a List node, so we can call
|
||||
* expression_tree_mutator directly rather than recursing to self.
|
||||
* either NIL or a List node, so we can call expression_tree_mutator
|
||||
* directly rather than recursing to self.
|
||||
*/
|
||||
args = (List *) expression_tree_mutator((Node *) expr->args,
|
||||
eval_const_expressions_mutator,
|
||||
eval_const_expressions_mutator,
|
||||
(void *) context);
|
||||
|
||||
/*
|
||||
* Code for op/func reduction is pretty bulky, so split it out as
|
||||
* a separate function.
|
||||
* Code for op/func reduction is pretty bulky, so split it out as a
|
||||
* separate function.
|
||||
*/
|
||||
simple = simplify_function(expr->funcid, expr->funcresulttype, args,
|
||||
true, context);
|
||||
@@ -1312,8 +1309,8 @@ eval_const_expressions_mutator(Node *node,
|
||||
|
||||
/*
|
||||
* The expression cannot be simplified any further, so build and
|
||||
* return a replacement FuncExpr node using the
|
||||
* possibly-simplified arguments.
|
||||
* return a replacement FuncExpr node using the possibly-simplified
|
||||
* arguments.
|
||||
*/
|
||||
newexpr = makeNode(FuncExpr);
|
||||
newexpr->funcid = expr->funcid;
|
||||
@@ -1331,23 +1328,23 @@ eval_const_expressions_mutator(Node *node,
|
||||
OpExpr *newexpr;
|
||||
|
||||
/*
|
||||
* Reduce constants in the OpExpr's arguments. We know args is
|
||||
* either NIL or a List node, so we can call
|
||||
* expression_tree_mutator directly rather than recursing to self.
|
||||
* Reduce constants in the OpExpr's arguments. We know args is either
|
||||
* NIL or a List node, so we can call expression_tree_mutator directly
|
||||
* rather than recursing to self.
|
||||
*/
|
||||
args = (List *) expression_tree_mutator((Node *) expr->args,
|
||||
eval_const_expressions_mutator,
|
||||
eval_const_expressions_mutator,
|
||||
(void *) context);
|
||||
|
||||
/*
|
||||
* Need to get OID of underlying function. Okay to scribble on
|
||||
* input to this extent.
|
||||
* Need to get OID of underlying function. Okay to scribble on input
|
||||
* to this extent.
|
||||
*/
|
||||
set_opfuncid(expr);
|
||||
|
||||
/*
|
||||
* Code for op/func reduction is pretty bulky, so split it out as
|
||||
* a separate function.
|
||||
* Code for op/func reduction is pretty bulky, so split it out as a
|
||||
* separate function.
|
||||
*/
|
||||
simple = simplify_function(expr->opfuncid, expr->opresulttype, args,
|
||||
true, context);
|
||||
@@ -1355,8 +1352,8 @@ eval_const_expressions_mutator(Node *node,
|
||||
return (Node *) simple;
|
||||
|
||||
/*
|
||||
* If the operator is boolean equality, we know how to simplify
|
||||
* cases involving one constant and one non-constant argument.
|
||||
* If the operator is boolean equality, we know how to simplify cases
|
||||
* involving one constant and one non-constant argument.
|
||||
*/
|
||||
if (expr->opno == BooleanEqualOperator)
|
||||
{
|
||||
@@ -1390,18 +1387,17 @@ eval_const_expressions_mutator(Node *node,
|
||||
DistinctExpr *newexpr;
|
||||
|
||||
/*
|
||||
* Reduce constants in the DistinctExpr's arguments. We know args
|
||||
* is either NIL or a List node, so we can call
|
||||
* expression_tree_mutator directly rather than recursing to self.
|
||||
* Reduce constants in the DistinctExpr's arguments. We know args is
|
||||
* either NIL or a List node, so we can call expression_tree_mutator
|
||||
* directly rather than recursing to self.
|
||||
*/
|
||||
args = (List *) expression_tree_mutator((Node *) expr->args,
|
||||
eval_const_expressions_mutator,
|
||||
eval_const_expressions_mutator,
|
||||
(void *) context);
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
@@ -1429,15 +1425,14 @@ eval_const_expressions_mutator(Node *node,
|
||||
/* (NOT okay to try to inline it, though!) */
|
||||
|
||||
/*
|
||||
* Need to get OID of underlying function. Okay to scribble
|
||||
* on input to this extent.
|
||||
* Need to get OID of underlying function. Okay to 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 a separate function.
|
||||
* Code for op/func reduction is pretty bulky, so split it out as
|
||||
* a separate function.
|
||||
*/
|
||||
simple = simplify_function(expr->opfuncid, expr->opresulttype,
|
||||
args, false, context);
|
||||
@@ -1482,7 +1477,7 @@ eval_const_expressions_mutator(Node *node,
|
||||
bool forceTrue = false;
|
||||
|
||||
newargs = simplify_or_arguments(expr->args, context,
|
||||
&haveNull, &forceTrue);
|
||||
&haveNull, &forceTrue);
|
||||
if (forceTrue)
|
||||
return makeBoolConst(true, false);
|
||||
if (haveNull)
|
||||
@@ -1503,7 +1498,7 @@ eval_const_expressions_mutator(Node *node,
|
||||
bool forceFalse = false;
|
||||
|
||||
newargs = simplify_and_arguments(expr->args, context,
|
||||
&haveNull, &forceFalse);
|
||||
&haveNull, &forceFalse);
|
||||
if (forceFalse)
|
||||
return makeBoolConst(false, false);
|
||||
if (haveNull)
|
||||
@@ -1554,17 +1549,17 @@ eval_const_expressions_mutator(Node *node,
|
||||
/*
|
||||
* Return a SubPlan unchanged --- too late to do anything with it.
|
||||
*
|
||||
* XXX should we ereport() here instead? Probably this routine
|
||||
* should never be invoked after SubPlan creation.
|
||||
* XXX should we ereport() here instead? Probably this routine should
|
||||
* never be invoked after SubPlan creation.
|
||||
*/
|
||||
return node;
|
||||
}
|
||||
if (IsA(node, RelabelType))
|
||||
{
|
||||
/*
|
||||
* If we can simplify the input to a constant, then we don't need
|
||||
* the RelabelType node anymore: just change the type field of the
|
||||
* Const node. Otherwise, must copy the RelabelType node.
|
||||
* If we can simplify the input to a constant, then we don't need the
|
||||
* RelabelType node anymore: just change the type field of the Const
|
||||
* node. Otherwise, must copy the RelabelType node.
|
||||
*/
|
||||
RelabelType *relabel = (RelabelType *) node;
|
||||
Node *arg;
|
||||
@@ -1573,8 +1568,8 @@ eval_const_expressions_mutator(Node *node,
|
||||
context);
|
||||
|
||||
/*
|
||||
* If we find stacked RelabelTypes (eg, from foo :: int :: oid) we
|
||||
* can discard all but the top one.
|
||||
* If we find stacked RelabelTypes (eg, from foo :: int :: oid) we can
|
||||
* discard all but the top one.
|
||||
*/
|
||||
while (arg && IsA(arg, RelabelType))
|
||||
arg = (Node *) ((RelabelType *) arg)->arg;
|
||||
@@ -1586,10 +1581,9 @@ eval_const_expressions_mutator(Node *node,
|
||||
con->consttype = relabel->resulttype;
|
||||
|
||||
/*
|
||||
* relabel's resulttypmod is discarded, which is OK for now;
|
||||
* if the type actually needs a runtime length coercion then
|
||||
* there should be a function call to do it just above this
|
||||
* node.
|
||||
* relabel's resulttypmod is discarded, which is OK for now; if
|
||||
* the type actually needs a runtime length coercion then there
|
||||
* should be a function call to do it just above this node.
|
||||
*/
|
||||
return (Node *) con;
|
||||
}
|
||||
@@ -1692,7 +1686,7 @@ eval_const_expressions_mutator(Node *node,
|
||||
|
||||
/*
|
||||
* Found a TRUE condition, so none of the remaining alternatives
|
||||
* can be reached. We treat the result as the default result.
|
||||
* can be reached. We treat the result as the default result.
|
||||
*/
|
||||
defresult = caseresult;
|
||||
break;
|
||||
@@ -1720,9 +1714,9 @@ eval_const_expressions_mutator(Node *node,
|
||||
if (IsA(node, CaseTestExpr))
|
||||
{
|
||||
/*
|
||||
* If we know a constant test value for the current CASE
|
||||
* construct, substitute it for the placeholder. Else just
|
||||
* return the placeholder as-is.
|
||||
* If we know a constant test value for the current CASE construct,
|
||||
* substitute it for the placeholder. Else just return the
|
||||
* placeholder as-is.
|
||||
*/
|
||||
if (context->case_val)
|
||||
return copyObject(context->case_val);
|
||||
@@ -1803,15 +1797,15 @@ eval_const_expressions_mutator(Node *node,
|
||||
if (IsA(node, FieldSelect))
|
||||
{
|
||||
/*
|
||||
* We can optimize field selection from a whole-row Var into a
|
||||
* simple Var. (This case won't be generated directly by the
|
||||
* parser, because ParseComplexProjection short-circuits it. But
|
||||
* it can arise while simplifying functions.) Also, we can
|
||||
* optimize field selection from a RowExpr construct.
|
||||
* We can optimize field selection from a whole-row Var into a simple
|
||||
* Var. (This case won't be generated directly by the parser, because
|
||||
* ParseComplexProjection short-circuits it. But it can arise while
|
||||
* simplifying functions.) Also, we can optimize field selection from
|
||||
* a RowExpr construct.
|
||||
*
|
||||
* We must however check that the declared type of the field is still
|
||||
* the same as when the FieldSelect was created --- this can
|
||||
* change if someone did ALTER COLUMN TYPE on the rowtype.
|
||||
* We must however check that the declared type of the field is still the
|
||||
* same as when the FieldSelect was created --- this can change if
|
||||
* someone did ALTER COLUMN TYPE on the rowtype.
|
||||
*/
|
||||
FieldSelect *fselect = (FieldSelect *) node;
|
||||
FieldSelect *newfselect;
|
||||
@@ -1840,7 +1834,7 @@ eval_const_expressions_mutator(Node *node,
|
||||
fselect->fieldnum <= list_length(rowexpr->args))
|
||||
{
|
||||
Node *fld = (Node *) list_nth(rowexpr->args,
|
||||
fselect->fieldnum - 1);
|
||||
fselect->fieldnum - 1);
|
||||
|
||||
if (rowtype_field_matches(rowexpr->row_typeid,
|
||||
fselect->fieldnum,
|
||||
@@ -1861,10 +1855,10 @@ eval_const_expressions_mutator(Node *node,
|
||||
|
||||
/*
|
||||
* For any node type not handled above, we recurse using
|
||||
* expression_tree_mutator, which will copy the node unchanged but try
|
||||
* to simplify its arguments (if any) using this routine. For example:
|
||||
* we cannot eliminate an ArrayRef node, but we might be able to
|
||||
* simplify constant expressions in its subscripts.
|
||||
* expression_tree_mutator, which will copy the node unchanged but try to
|
||||
* simplify its arguments (if any) using this routine. For example: we
|
||||
* cannot eliminate an ArrayRef node, but we might be able to simplify
|
||||
* constant expressions in its subscripts.
|
||||
*/
|
||||
return expression_tree_mutator(node, eval_const_expressions_mutator,
|
||||
(void *) context);
|
||||
@@ -1900,7 +1894,7 @@ simplify_or_arguments(List *args,
|
||||
/*
|
||||
* Since the parser considers OR to be a binary operator, long OR lists
|
||||
* become deeply nested expressions. We must flatten these into long
|
||||
* argument lists of a single OR operator. To avoid blowing out the stack
|
||||
* argument lists of a single OR operator. To avoid blowing out the stack
|
||||
* with recursion of eval_const_expressions, we resort to some tenseness
|
||||
* here: we keep a list of not-yet-processed inputs, and handle flattening
|
||||
* of nested ORs by prepending to the to-do list instead of recursing.
|
||||
@@ -1915,14 +1909,14 @@ simplify_or_arguments(List *args,
|
||||
/* flatten nested ORs as per above comment */
|
||||
if (or_clause(arg))
|
||||
{
|
||||
List *subargs = list_copy(((BoolExpr *) arg)->args);
|
||||
List *subargs = list_copy(((BoolExpr *) arg)->args);
|
||||
|
||||
/* overly tense code to avoid leaking unused list header */
|
||||
if (!unprocessed_args)
|
||||
unprocessed_args = subargs;
|
||||
else
|
||||
{
|
||||
List *oldhdr = unprocessed_args;
|
||||
List *oldhdr = unprocessed_args;
|
||||
|
||||
unprocessed_args = list_concat(subargs, unprocessed_args);
|
||||
pfree(oldhdr);
|
||||
@@ -1934,23 +1928,22 @@ simplify_or_arguments(List *args,
|
||||
arg = eval_const_expressions_mutator(arg, context);
|
||||
|
||||
/*
|
||||
* It is unlikely but not impossible for simplification of a
|
||||
* non-OR clause to produce an OR. Recheck, but don't be
|
||||
* too tense about it since it's not a mainstream case.
|
||||
* In particular we don't worry about const-simplifying
|
||||
* the input twice.
|
||||
* It is unlikely but not impossible for simplification of a non-OR
|
||||
* clause to produce an OR. Recheck, but don't be too tense about it
|
||||
* since it's not a mainstream case. In particular we don't worry
|
||||
* about const-simplifying the input twice.
|
||||
*/
|
||||
if (or_clause(arg))
|
||||
{
|
||||
List *subargs = list_copy(((BoolExpr *) arg)->args);
|
||||
List *subargs = list_copy(((BoolExpr *) arg)->args);
|
||||
|
||||
unprocessed_args = list_concat(subargs, unprocessed_args);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we have a const-simplified non-OR argument. Process it
|
||||
* per comments above.
|
||||
* OK, we have a const-simplified non-OR argument. Process it per
|
||||
* comments above.
|
||||
*/
|
||||
if (IsA(arg, Const))
|
||||
{
|
||||
@@ -2018,14 +2011,14 @@ simplify_and_arguments(List *args,
|
||||
/* flatten nested ANDs as per above comment */
|
||||
if (and_clause(arg))
|
||||
{
|
||||
List *subargs = list_copy(((BoolExpr *) arg)->args);
|
||||
List *subargs = list_copy(((BoolExpr *) arg)->args);
|
||||
|
||||
/* overly tense code to avoid leaking unused list header */
|
||||
if (!unprocessed_args)
|
||||
unprocessed_args = subargs;
|
||||
else
|
||||
{
|
||||
List *oldhdr = unprocessed_args;
|
||||
List *oldhdr = unprocessed_args;
|
||||
|
||||
unprocessed_args = list_concat(subargs, unprocessed_args);
|
||||
pfree(oldhdr);
|
||||
@@ -2037,23 +2030,22 @@ simplify_and_arguments(List *args,
|
||||
arg = eval_const_expressions_mutator(arg, context);
|
||||
|
||||
/*
|
||||
* It is unlikely but not impossible for simplification of a
|
||||
* non-AND clause to produce an AND. Recheck, but don't be
|
||||
* too tense about it since it's not a mainstream case.
|
||||
* In particular we don't worry about const-simplifying
|
||||
* the input twice.
|
||||
* It is unlikely but not impossible for simplification of a non-AND
|
||||
* clause to produce an AND. Recheck, but don't be too tense about it
|
||||
* since it's not a mainstream case. In particular we don't worry
|
||||
* about const-simplifying the input twice.
|
||||
*/
|
||||
if (and_clause(arg))
|
||||
{
|
||||
List *subargs = list_copy(((BoolExpr *) arg)->args);
|
||||
List *subargs = list_copy(((BoolExpr *) arg)->args);
|
||||
|
||||
unprocessed_args = list_concat(subargs, unprocessed_args);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we have a const-simplified non-AND argument. Process it
|
||||
* per comments above.
|
||||
* OK, we have a const-simplified non-AND argument. Process it per
|
||||
* comments above.
|
||||
*/
|
||||
if (IsA(arg, Const))
|
||||
{
|
||||
@@ -2111,7 +2103,7 @@ simplify_boolean_equality(List *args)
|
||||
{
|
||||
Assert(!((Const *) leftop)->constisnull);
|
||||
if (DatumGetBool(((Const *) leftop)->constvalue))
|
||||
return rightop; /* true = foo */
|
||||
return rightop; /* true = foo */
|
||||
else
|
||||
return make_notclause(rightop); /* false = foo */
|
||||
}
|
||||
@@ -2119,7 +2111,7 @@ simplify_boolean_equality(List *args)
|
||||
{
|
||||
Assert(!((Const *) rightop)->constisnull);
|
||||
if (DatumGetBool(((Const *) rightop)->constvalue))
|
||||
return leftop; /* foo = true */
|
||||
return leftop; /* foo = true */
|
||||
else
|
||||
return make_notclause(leftop); /* foo = false */
|
||||
}
|
||||
@@ -2146,12 +2138,12 @@ simplify_function(Oid funcid, Oid result_type, List *args,
|
||||
Expr *newexpr;
|
||||
|
||||
/*
|
||||
* We have two strategies for simplification: either execute the
|
||||
* function to deliver a constant result, or expand in-line the body
|
||||
* of the function definition (which only works for simple
|
||||
* SQL-language functions, but that is a common case). In either case
|
||||
* we need access to the function's pg_proc tuple, so fetch it just
|
||||
* once to use in both attempts.
|
||||
* We have two strategies for simplification: either execute the function
|
||||
* to deliver a constant result, or expand in-line the body of the
|
||||
* function definition (which only works for simple SQL-language
|
||||
* functions, but that is a common case). In either case we need access
|
||||
* to the function's pg_proc tuple, so fetch it just once to use in both
|
||||
* attempts.
|
||||
*/
|
||||
func_tuple = SearchSysCache(PROCOID,
|
||||
ObjectIdGetDatum(funcid),
|
||||
@@ -2200,15 +2192,15 @@ evaluate_function(Oid funcid, Oid result_type, List *args,
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Can't simplify if it returns RECORD. The immediate problem is that
|
||||
* it will be needing an expected tupdesc which we can't supply here.
|
||||
* Can't simplify if it returns RECORD. The immediate problem is that it
|
||||
* will be needing an expected tupdesc which we can't supply here.
|
||||
*
|
||||
* In the case where it has OUT parameters, it could get by without an
|
||||
* expected tupdesc, but we still have issues: get_expr_result_type()
|
||||
* doesn't know how to extract type info from a RECORD constant, and
|
||||
* in the case of a NULL function result there doesn't seem to be any
|
||||
* clean way to fix that. In view of the likelihood of there being
|
||||
* still other gotchas, seems best to leave the function call unreduced.
|
||||
* doesn't know how to extract type info from a RECORD constant, and in
|
||||
* the case of a NULL function result there doesn't seem to be any clean
|
||||
* way to fix that. In view of the likelihood of there being still other
|
||||
* gotchas, seems best to leave the function call unreduced.
|
||||
*/
|
||||
if (funcform->prorettype == RECORDOID)
|
||||
return NULL;
|
||||
@@ -2225,10 +2217,10 @@ evaluate_function(Oid funcid, Oid result_type, List *args,
|
||||
}
|
||||
|
||||
/*
|
||||
* If the function is strict and has a constant-NULL input, it will
|
||||
* never be called at all, so we can replace the call by a NULL
|
||||
* constant, even if there are other inputs that aren't constant, and
|
||||
* even if the function is not otherwise immutable.
|
||||
* If the function is strict and has a constant-NULL input, it will never
|
||||
* be called at all, so we can replace the call by a NULL constant, even
|
||||
* if there are other inputs that aren't constant, and even if the
|
||||
* function is not otherwise immutable.
|
||||
*/
|
||||
if (funcform->proisstrict && has_null_input)
|
||||
return (Expr *) makeNullConst(result_type);
|
||||
@@ -2242,16 +2234,16 @@ evaluate_function(Oid funcid, Oid result_type, List *args,
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Ordinarily we are only allowed to simplify immutable functions.
|
||||
* But for purposes of estimation, we consider it okay to simplify
|
||||
* functions that are merely stable; the risk that the result might
|
||||
* change from planning time to execution time is worth taking in
|
||||
* preference to not being able to estimate the value at all.
|
||||
* Ordinarily we are only allowed to simplify immutable functions. But for
|
||||
* purposes of estimation, we consider it okay to simplify functions that
|
||||
* are merely stable; the risk that the result might change from planning
|
||||
* time to execution time is worth taking in preference to not being able
|
||||
* to estimate the value at all.
|
||||
*/
|
||||
if (funcform->provolatile == PROVOLATILE_IMMUTABLE)
|
||||
/* okay */ ;
|
||||
/* okay */ ;
|
||||
else if (context->estimate && funcform->provolatile == PROVOLATILE_STABLE)
|
||||
/* okay */ ;
|
||||
/* okay */ ;
|
||||
else
|
||||
return NULL;
|
||||
|
||||
@@ -2318,8 +2310,8 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Forget it if the function is not SQL-language or has other
|
||||
* showstopper properties. (The nargs check is just paranoia.)
|
||||
* Forget it if the function is not SQL-language or has other showstopper
|
||||
* properties. (The nargs check is just paranoia.)
|
||||
*/
|
||||
if (funcform->prolang != SQLlanguageId ||
|
||||
funcform->prosecdef ||
|
||||
@@ -2336,8 +2328,8 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Setup error traceback support for ereport(). This is so that we
|
||||
* can finger the function that bad information came from.
|
||||
* Setup error traceback support for ereport(). This is so that we can
|
||||
* finger the function that bad information came from.
|
||||
*/
|
||||
sqlerrcontext.callback = sql_inline_error_callback;
|
||||
sqlerrcontext.arg = func_tuple;
|
||||
@@ -2345,8 +2337,8 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
||||
error_context_stack = &sqlerrcontext;
|
||||
|
||||
/*
|
||||
* Make a temporary memory context, so that we don't leak all the
|
||||
* stuff that parsing might create.
|
||||
* Make a temporary memory context, so that we don't leak all the stuff
|
||||
* that parsing might create.
|
||||
*/
|
||||
mycxt = AllocSetContextCreate(CurrentMemoryContext,
|
||||
"inline_function",
|
||||
@@ -2383,10 +2375,10 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
||||
src = DatumGetCString(DirectFunctionCall1(textout, tmp));
|
||||
|
||||
/*
|
||||
* We just do parsing and parse analysis, not rewriting, because
|
||||
* rewriting will not affect table-free-SELECT-only queries, which is
|
||||
* all that we care about. Also, we can punt as soon as we detect
|
||||
* more than one command in the function body.
|
||||
* We just do parsing and parse analysis, not rewriting, because rewriting
|
||||
* will not affect table-free-SELECT-only queries, which is all that we
|
||||
* care about. Also, we can punt as soon as we detect more than one
|
||||
* command in the function body.
|
||||
*/
|
||||
raw_parsetree_list = pg_parse_query(src);
|
||||
if (list_length(raw_parsetree_list) != 1)
|
||||
@@ -2425,24 +2417,24 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
||||
newexpr = (Node *) ((TargetEntry *) linitial(querytree->targetList))->expr;
|
||||
|
||||
/*
|
||||
* If the function has any arguments declared as polymorphic types,
|
||||
* then it wasn't type-checked at definition time; must do so now.
|
||||
* (This will raise an error if wrong, but that's okay since the
|
||||
* function would fail at runtime anyway. Note we do not try this
|
||||
* until we have verified that no rewriting was needed; that's
|
||||
* probably not important, but let's be careful.)
|
||||
* If the function has any arguments declared as polymorphic types, then
|
||||
* it wasn't type-checked at definition time; must do so now. (This will
|
||||
* raise an error if wrong, but that's okay since the function would fail
|
||||
* at runtime anyway. Note we do not try this until we have verified that
|
||||
* no rewriting was needed; that's probably not important, but let's be
|
||||
* careful.)
|
||||
*/
|
||||
if (polymorphic)
|
||||
(void) check_sql_fn_retval(funcid, result_type, querytree_list, NULL);
|
||||
|
||||
/*
|
||||
* Additional validity checks on the expression. It mustn't return a
|
||||
* set, and it mustn't be more volatile than the surrounding function
|
||||
* (this is to avoid breaking hacks that involve pretending a function
|
||||
* is immutable when it really ain't). If the surrounding function is
|
||||
* declared strict, then the expression must contain only strict
|
||||
* constructs and must use all of the function parameters (this is
|
||||
* overkill, but an exact analysis is hard).
|
||||
* Additional validity checks on the expression. It mustn't return a set,
|
||||
* and it mustn't be more volatile than the surrounding function (this is
|
||||
* to avoid breaking hacks that involve pretending a function is immutable
|
||||
* when it really ain't). If the surrounding function is declared strict,
|
||||
* then the expression must contain only strict constructs and must use
|
||||
* all of the function parameters (this is overkill, but an exact analysis
|
||||
* is hard).
|
||||
*/
|
||||
if (expression_returns_set(newexpr))
|
||||
goto fail;
|
||||
@@ -2459,10 +2451,10 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* We may be able to do it; there are still checks on parameter usage
|
||||
* to make, but those are most easily done in combination with the
|
||||
* actual substitution of the inputs. So start building expression
|
||||
* with inputs substituted.
|
||||
* We may be able to do it; there are still checks on parameter usage to
|
||||
* make, but those are most easily done in combination with the actual
|
||||
* substitution of the inputs. So start building expression with inputs
|
||||
* substituted.
|
||||
*/
|
||||
usecounts = (int *) palloc0(funcform->pronargs * sizeof(int));
|
||||
newexpr = substitute_actual_parameters(newexpr, funcform->pronargs,
|
||||
@@ -2486,8 +2478,8 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
||||
QualCost eval_cost;
|
||||
|
||||
/*
|
||||
* We define "expensive" as "contains any subplan or more than
|
||||
* 10 operators". Note that the subplan search has to be done
|
||||
* We define "expensive" as "contains any subplan or more than 10
|
||||
* operators". Note that the subplan search has to be done
|
||||
* explicitly, since cost_qual_eval() will barf on unplanned
|
||||
* subselects.
|
||||
*/
|
||||
@@ -2509,8 +2501,8 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
||||
}
|
||||
|
||||
/*
|
||||
* Whew --- we can make the substitution. Copy the modified
|
||||
* expression out of the temporary memory context, and clean up.
|
||||
* Whew --- we can make the substitution. Copy the modified expression
|
||||
* out of the temporary memory context, and clean up.
|
||||
*/
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
@@ -2519,8 +2511,8 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
||||
MemoryContextDelete(mycxt);
|
||||
|
||||
/*
|
||||
* Recursively try to simplify the modified expression. Here we must
|
||||
* add the current function to the context list of active functions.
|
||||
* Recursively try to simplify the modified expression. Here we must add
|
||||
* the current function to the context list of active functions.
|
||||
*/
|
||||
context->active_fns = lcons_oid(funcid, context->active_fns);
|
||||
newexpr = eval_const_expressions_mutator(newexpr, context);
|
||||
@@ -2557,7 +2549,7 @@ substitute_actual_parameters(Node *expr, int nargs, List *args,
|
||||
|
||||
static Node *
|
||||
substitute_actual_parameters_mutator(Node *node,
|
||||
substitute_actual_parameters_context *context)
|
||||
substitute_actual_parameters_context *context)
|
||||
{
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
@@ -2646,10 +2638,10 @@ evaluate_expr(Expr *expr, Oid result_type)
|
||||
/*
|
||||
* And evaluate it.
|
||||
*
|
||||
* It is OK to use a default econtext because none of the ExecEvalExpr()
|
||||
* code used in this situation will use econtext. That might seem
|
||||
* fortuitous, but it's not so unreasonable --- a constant expression
|
||||
* does not depend on context, by definition, n'est ce pas?
|
||||
* It is OK to use a default econtext because none of the ExecEvalExpr() code
|
||||
* used in this situation will use econtext. That might seem fortuitous,
|
||||
* but it's not so unreasonable --- a constant expression does not depend
|
||||
* on context, by definition, n'est ce pas?
|
||||
*/
|
||||
const_val = ExecEvalExprSwitchContext(exprstate,
|
||||
GetPerTupleExprContext(estate),
|
||||
@@ -2779,12 +2771,12 @@ expression_tree_walker(Node *node,
|
||||
ListCell *temp;
|
||||
|
||||
/*
|
||||
* The walker has already visited the current node, and so we need
|
||||
* only recurse into any sub-nodes it has.
|
||||
* The walker has already visited the current node, and so we need only
|
||||
* recurse into any sub-nodes it has.
|
||||
*
|
||||
* We assume that the walker is not interested in List nodes per se, so
|
||||
* when we expect a List we just recurse directly to self without
|
||||
* bothering to call the walker.
|
||||
* We assume that the walker is not interested in List nodes per se, so when
|
||||
* we expect a List we just recurse directly to self without bothering to
|
||||
* call the walker.
|
||||
*/
|
||||
if (node == NULL)
|
||||
return false;
|
||||
@@ -2877,8 +2869,8 @@ expression_tree_walker(Node *node,
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Also invoke the walker on the sublink's Query node, so
|
||||
* it can recurse into the sub-query if it wants to.
|
||||
* Also invoke the walker on the sublink's Query node, so it
|
||||
* can recurse into the sub-query if it wants to.
|
||||
*/
|
||||
return walker(sublink->subselect, context);
|
||||
}
|
||||
@@ -3167,8 +3159,8 @@ expression_tree_mutator(Node *node,
|
||||
void *context)
|
||||
{
|
||||
/*
|
||||
* The mutator has already decided not to modify the current node, but
|
||||
* we must call the mutator for any sub-nodes.
|
||||
* The mutator has already decided not to modify the current node, but we
|
||||
* must call the mutator for any sub-nodes.
|
||||
*/
|
||||
|
||||
#define FLATCOPY(newnode, node, nodetype) \
|
||||
@@ -3286,8 +3278,8 @@ expression_tree_mutator(Node *node,
|
||||
MUTATE(newnode->lefthand, sublink->lefthand, List *);
|
||||
|
||||
/*
|
||||
* Also invoke the mutator on the sublink's Query node, so
|
||||
* it can recurse into the sub-query if it wants to.
|
||||
* Also invoke the mutator on the sublink's Query node, so it
|
||||
* can recurse into the sub-query if it wants to.
|
||||
*/
|
||||
MUTATE(newnode->subselect, sublink->subselect, Node *);
|
||||
return (Node *) newnode;
|
||||
@@ -3468,10 +3460,9 @@ expression_tree_mutator(Node *node,
|
||||
case T_List:
|
||||
{
|
||||
/*
|
||||
* We assume the mutator isn't interested in the list
|
||||
* nodes per se, so just invoke it on each list element.
|
||||
* NOTE: this would fail badly on a list with integer
|
||||
* elements!
|
||||
* We assume the mutator isn't interested in the list nodes
|
||||
* per se, so just invoke it on each list element. NOTE: this
|
||||
* would fail badly on a list with integer elements!
|
||||
*/
|
||||
List *resultlist;
|
||||
ListCell *temp;
|
||||
|
||||
Reference in New Issue
Block a user