mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Fix up the remaining places where the expression node structure would lose
available information about the typmod of an expression; namely, Const, ArrayRef, ArrayExpr, and EXPR and ARRAY SubLinks. In the ArrayExpr and SubLink cases it wasn't really the data structure's fault, but exprTypmod() being lazy. This seems like a good idea in view of the expected increase in typmod usage from Teodor's work to allow user-defined types to have typmods. In particular this responds to the concerns we had about eliminating the special-purpose hack that exprTypmod() used to have for BPCHAR Consts. We can now tell whether or not such a Const has been cast to a specific length, and report or display properly if so. initdb forced due to changes in stored rules.
This commit is contained in:
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.216 2007/01/20 20:45:39 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.217 2007/03/17 00:11:04 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -2628,7 +2628,7 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop)
|
||||
|
||||
expr = make_opclause(opr1oid, BOOLOID, false,
|
||||
(Expr *) leftop,
|
||||
(Expr *) makeConst(datatype, -1, opr1right,
|
||||
(Expr *) makeConst(datatype, -1, -1, opr1right,
|
||||
false, false));
|
||||
result = list_make1(make_restrictinfo(expr, true, false, false, NULL));
|
||||
|
||||
@ -2643,7 +2643,7 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop)
|
||||
|
||||
expr = make_opclause(opr2oid, BOOLOID, false,
|
||||
(Expr *) leftop,
|
||||
(Expr *) makeConst(datatype, -1, opr2right,
|
||||
(Expr *) makeConst(datatype, -1, -1, opr2right,
|
||||
false, false));
|
||||
result = lappend(result,
|
||||
make_restrictinfo(expr, true, false, false, NULL));
|
||||
@ -2683,6 +2683,7 @@ string_to_const(const char *str, Oid datatype)
|
||||
{
|
||||
Datum conval = string_to_datum(str, datatype);
|
||||
|
||||
return makeConst(datatype, ((datatype == NAMEOID) ? NAMEDATALEN : -1),
|
||||
return makeConst(datatype, -1,
|
||||
((datatype == NAMEOID) ? NAMEDATALEN : -1),
|
||||
conval, false, false);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.29 2007/02/22 22:00:24 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.30 2007/03/17 00:11:04 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -477,7 +477,7 @@ make_agg_subplan(PlannerInfo *root, MinMaxAggInfo *info)
|
||||
|
||||
/* set up LIMIT 1 */
|
||||
subparse->limitOffset = NULL;
|
||||
subparse->limitCount = (Node *) makeConst(INT8OID, sizeof(int64),
|
||||
subparse->limitCount = (Node *) makeConst(INT8OID, -1, sizeof(int64),
|
||||
Int64GetDatum(1),
|
||||
false, false /* not by val */ );
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.86 2007/02/19 07:03:30 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.87 2007/03/17 00:11:04 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -281,6 +281,7 @@ expand_targetlist(List *tlist, int command_type,
|
||||
if (!att_tup->attisdropped)
|
||||
{
|
||||
new_expr = (Node *) makeConst(atttype,
|
||||
-1,
|
||||
att_tup->attlen,
|
||||
(Datum) 0,
|
||||
true, /* isnull */
|
||||
@ -296,6 +297,7 @@ expand_targetlist(List *tlist, int command_type,
|
||||
{
|
||||
/* Insert NULL for dropped column */
|
||||
new_expr = (Node *) makeConst(INT4OID,
|
||||
-1,
|
||||
sizeof(int32),
|
||||
(Datum) 0,
|
||||
true, /* isnull */
|
||||
@ -315,6 +317,7 @@ expand_targetlist(List *tlist, int command_type,
|
||||
{
|
||||
/* Insert NULL for dropped column */
|
||||
new_expr = (Node *) makeConst(INT4OID,
|
||||
-1,
|
||||
sizeof(int32),
|
||||
(Datum) 0,
|
||||
true, /* isnull */
|
||||
|
@ -22,7 +22,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.139 2007/02/22 22:00:24 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.140 2007/03/17 00:11:04 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -545,6 +545,7 @@ generate_setop_tlist(List *colTypes, int flag,
|
||||
/* Add a resjunk flag column */
|
||||
/* flag value is the given constant */
|
||||
expr = (Node *) makeConst(INT4OID,
|
||||
-1,
|
||||
sizeof(int4),
|
||||
Int32GetDatum(flag),
|
||||
false,
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.238 2007/03/13 00:33:41 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.239 2007/03/17 00:11:04 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -82,10 +82,12 @@ static List *simplify_and_arguments(List *args,
|
||||
eval_const_expressions_context *context,
|
||||
bool *haveNull, bool *forceFalse);
|
||||
static Expr *simplify_boolean_equality(List *args);
|
||||
static Expr *simplify_function(Oid funcid, Oid result_type, List *args,
|
||||
static Expr *simplify_function(Oid funcid,
|
||||
Oid result_type, int32 result_typmod, List *args,
|
||||
bool allow_inline,
|
||||
eval_const_expressions_context *context);
|
||||
static Expr *evaluate_function(Oid funcid, Oid result_type, List *args,
|
||||
static Expr *evaluate_function(Oid funcid,
|
||||
Oid result_type, int32 result_typmod, List *args,
|
||||
HeapTuple func_tuple,
|
||||
eval_const_expressions_context *context);
|
||||
static Expr *inline_function(Oid funcid, Oid result_type, List *args,
|
||||
@ -96,7 +98,7 @@ static Node *substitute_actual_parameters(Node *expr, int nargs, List *args,
|
||||
static Node *substitute_actual_parameters_mutator(Node *node,
|
||||
substitute_actual_parameters_context *context);
|
||||
static void sql_inline_error_callback(void *arg);
|
||||
static Expr *evaluate_expr(Expr *expr, Oid result_type);
|
||||
static Expr *evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
@ -934,8 +936,6 @@ contain_nonstrict_functions_walker(Node *node, void *context)
|
||||
return true;
|
||||
if (IsA(node, CaseExpr))
|
||||
return true;
|
||||
if (IsA(node, CaseWhen))
|
||||
return true;
|
||||
if (IsA(node, ArrayExpr))
|
||||
return true;
|
||||
if (IsA(node, RowExpr))
|
||||
@ -1654,6 +1654,7 @@ eval_const_expressions_mutator(Node *node,
|
||||
else
|
||||
pval = datumCopy(prm->value, typByVal, typLen);
|
||||
return (Node *) makeConst(param->paramtype,
|
||||
param->paramtypmod,
|
||||
(int) typLen,
|
||||
pval,
|
||||
prm->isnull,
|
||||
@ -1682,9 +1683,13 @@ eval_const_expressions_mutator(Node *node,
|
||||
|
||||
/*
|
||||
* Code for op/func reduction is pretty bulky, so split it out as a
|
||||
* separate function.
|
||||
* separate function. Note: exprTypmod normally returns -1 for a
|
||||
* FuncExpr, but not when the node is recognizably a length coercion;
|
||||
* we want to preserve the typmod in the eventual Const if so.
|
||||
*/
|
||||
simple = simplify_function(expr->funcid, expr->funcresulttype, args,
|
||||
simple = simplify_function(expr->funcid,
|
||||
expr->funcresulttype, exprTypmod(node),
|
||||
args,
|
||||
true, context);
|
||||
if (simple) /* successfully simplified it */
|
||||
return (Node *) simple;
|
||||
@ -1728,7 +1733,9 @@ eval_const_expressions_mutator(Node *node,
|
||||
* Code for op/func reduction is pretty bulky, so split it out as a
|
||||
* separate function.
|
||||
*/
|
||||
simple = simplify_function(expr->opfuncid, expr->opresulttype, args,
|
||||
simple = simplify_function(expr->opfuncid,
|
||||
expr->opresulttype, -1,
|
||||
args,
|
||||
true, context);
|
||||
if (simple) /* successfully simplified it */
|
||||
return (Node *) simple;
|
||||
@ -1816,8 +1823,10 @@ eval_const_expressions_mutator(Node *node,
|
||||
* 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);
|
||||
simple = simplify_function(expr->opfuncid,
|
||||
expr->opresulttype, -1,
|
||||
args,
|
||||
false, context);
|
||||
if (simple) /* successfully simplified it */
|
||||
{
|
||||
/*
|
||||
@ -1961,12 +1970,7 @@ eval_const_expressions_mutator(Node *node,
|
||||
Const *con = (Const *) arg;
|
||||
|
||||
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.
|
||||
*/
|
||||
con->consttypmod = relabel->resulttypmod;
|
||||
return (Node *) con;
|
||||
}
|
||||
else
|
||||
@ -2134,7 +2138,8 @@ eval_const_expressions_mutator(Node *node,
|
||||
|
||||
if (all_const)
|
||||
return (Node *) evaluate_expr((Expr *) newarray,
|
||||
newarray->array_typeid);
|
||||
newarray->array_typeid,
|
||||
exprTypmod(node));
|
||||
|
||||
return (Node *) newarray;
|
||||
}
|
||||
@ -2637,14 +2642,15 @@ simplify_boolean_equality(List *args)
|
||||
* (which might originally have been an operator; we don't care)
|
||||
*
|
||||
* Inputs are the function OID, actual result type OID (which is needed for
|
||||
* polymorphic functions), and the pre-simplified argument list;
|
||||
* polymorphic functions) and typmod, and the pre-simplified argument list;
|
||||
* also the context data for eval_const_expressions.
|
||||
*
|
||||
* Returns a simplified expression if successful, or NULL if cannot
|
||||
* simplify the function call.
|
||||
*/
|
||||
static Expr *
|
||||
simplify_function(Oid funcid, Oid result_type, List *args,
|
||||
simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
|
||||
List *args,
|
||||
bool allow_inline,
|
||||
eval_const_expressions_context *context)
|
||||
{
|
||||
@ -2665,7 +2671,7 @@ simplify_function(Oid funcid, Oid result_type, List *args,
|
||||
if (!HeapTupleIsValid(func_tuple))
|
||||
elog(ERROR, "cache lookup failed for function %u", funcid);
|
||||
|
||||
newexpr = evaluate_function(funcid, result_type, args,
|
||||
newexpr = evaluate_function(funcid, result_type, result_typmod, args,
|
||||
func_tuple, context);
|
||||
|
||||
if (!newexpr && allow_inline)
|
||||
@ -2689,7 +2695,7 @@ simplify_function(Oid funcid, Oid result_type, List *args,
|
||||
* simplify the function.
|
||||
*/
|
||||
static Expr *
|
||||
evaluate_function(Oid funcid, Oid result_type, List *args,
|
||||
evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, List *args,
|
||||
HeapTuple func_tuple,
|
||||
eval_const_expressions_context *context)
|
||||
{
|
||||
@ -2773,7 +2779,7 @@ evaluate_function(Oid funcid, Oid result_type, List *args,
|
||||
newexpr->funcformat = COERCE_DONTCARE; /* doesn't matter */
|
||||
newexpr->args = args;
|
||||
|
||||
return evaluate_expr((Expr *) newexpr, result_type);
|
||||
return evaluate_expr((Expr *) newexpr, result_type, result_typmod);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3133,7 +3139,7 @@ sql_inline_error_callback(void *arg)
|
||||
* code and ensure we get the same result as the executor would get.
|
||||
*/
|
||||
static Expr *
|
||||
evaluate_expr(Expr *expr, Oid result_type)
|
||||
evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod)
|
||||
{
|
||||
EState *estate;
|
||||
ExprState *exprstate;
|
||||
@ -3184,7 +3190,7 @@ evaluate_expr(Expr *expr, Oid result_type)
|
||||
/*
|
||||
* Make the constant result node.
|
||||
*/
|
||||
return (Expr *) makeConst(result_type, resultTypLen,
|
||||
return (Expr *) makeConst(result_type, result_typmod, resultTypLen,
|
||||
const_val, const_is_null,
|
||||
resultTypByVal);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.13 2007/01/05 22:19:33 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.14 2007/03/17 00:11:04 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -828,6 +828,7 @@ arrayconst_startup_fn(Node *clause, PredIterInfo info)
|
||||
/* Set up a dummy Const node to hold the per-element values */
|
||||
state->constexpr.xpr.type = T_Const;
|
||||
state->constexpr.consttype = ARR_ELEMTYPE(arrayval);
|
||||
state->constexpr.consttypmod = -1;
|
||||
state->constexpr.constlen = elmlen;
|
||||
state->constexpr.constbyval = elmbyval;
|
||||
lsecond(state->opexpr.args) = &state->constexpr;
|
||||
|
Reference in New Issue
Block a user