mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08: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:
parent
51d7741db1
commit
0f4ff460c4
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.370 2007/03/13 00:33:40 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.371 2007/03/17 00:11:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -773,6 +773,7 @@ _copyConst(Const *from)
|
|||||||
Const *newnode = makeNode(Const);
|
Const *newnode = makeNode(Const);
|
||||||
|
|
||||||
COPY_SCALAR_FIELD(consttype);
|
COPY_SCALAR_FIELD(consttype);
|
||||||
|
COPY_SCALAR_FIELD(consttypmod);
|
||||||
COPY_SCALAR_FIELD(constlen);
|
COPY_SCALAR_FIELD(constlen);
|
||||||
|
|
||||||
if (from->constbyval || from->constisnull)
|
if (from->constbyval || from->constisnull)
|
||||||
@ -841,9 +842,9 @@ _copyArrayRef(ArrayRef *from)
|
|||||||
{
|
{
|
||||||
ArrayRef *newnode = makeNode(ArrayRef);
|
ArrayRef *newnode = makeNode(ArrayRef);
|
||||||
|
|
||||||
COPY_SCALAR_FIELD(refrestype);
|
|
||||||
COPY_SCALAR_FIELD(refarraytype);
|
COPY_SCALAR_FIELD(refarraytype);
|
||||||
COPY_SCALAR_FIELD(refelemtype);
|
COPY_SCALAR_FIELD(refelemtype);
|
||||||
|
COPY_SCALAR_FIELD(reftypmod);
|
||||||
COPY_NODE_FIELD(refupperindexpr);
|
COPY_NODE_FIELD(refupperindexpr);
|
||||||
COPY_NODE_FIELD(reflowerindexpr);
|
COPY_NODE_FIELD(reflowerindexpr);
|
||||||
COPY_NODE_FIELD(refexpr);
|
COPY_NODE_FIELD(refexpr);
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.301 2007/03/13 00:33:40 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.302 2007/03/17 00:11:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -139,6 +139,7 @@ static bool
|
|||||||
_equalConst(Const *a, Const *b)
|
_equalConst(Const *a, Const *b)
|
||||||
{
|
{
|
||||||
COMPARE_SCALAR_FIELD(consttype);
|
COMPARE_SCALAR_FIELD(consttype);
|
||||||
|
COMPARE_SCALAR_FIELD(consttypmod);
|
||||||
COMPARE_SCALAR_FIELD(constlen);
|
COMPARE_SCALAR_FIELD(constlen);
|
||||||
COMPARE_SCALAR_FIELD(constisnull);
|
COMPARE_SCALAR_FIELD(constisnull);
|
||||||
COMPARE_SCALAR_FIELD(constbyval);
|
COMPARE_SCALAR_FIELD(constbyval);
|
||||||
@ -180,9 +181,9 @@ _equalAggref(Aggref *a, Aggref *b)
|
|||||||
static bool
|
static bool
|
||||||
_equalArrayRef(ArrayRef *a, ArrayRef *b)
|
_equalArrayRef(ArrayRef *a, ArrayRef *b)
|
||||||
{
|
{
|
||||||
COMPARE_SCALAR_FIELD(refrestype);
|
|
||||||
COMPARE_SCALAR_FIELD(refarraytype);
|
COMPARE_SCALAR_FIELD(refarraytype);
|
||||||
COMPARE_SCALAR_FIELD(refelemtype);
|
COMPARE_SCALAR_FIELD(refelemtype);
|
||||||
|
COMPARE_SCALAR_FIELD(reftypmod);
|
||||||
COMPARE_NODE_FIELD(refupperindexpr);
|
COMPARE_NODE_FIELD(refupperindexpr);
|
||||||
COMPARE_NODE_FIELD(reflowerindexpr);
|
COMPARE_NODE_FIELD(reflowerindexpr);
|
||||||
COMPARE_NODE_FIELD(refexpr);
|
COMPARE_NODE_FIELD(refexpr);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.54 2007/01/05 22:19:30 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.55 2007/03/17 00:11:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -140,6 +140,7 @@ flatCopyTargetEntry(TargetEntry *src_tle)
|
|||||||
*/
|
*/
|
||||||
Const *
|
Const *
|
||||||
makeConst(Oid consttype,
|
makeConst(Oid consttype,
|
||||||
|
int32 consttypmod,
|
||||||
int constlen,
|
int constlen,
|
||||||
Datum constvalue,
|
Datum constvalue,
|
||||||
bool constisnull,
|
bool constisnull,
|
||||||
@ -148,6 +149,7 @@ makeConst(Oid consttype,
|
|||||||
Const *cnst = makeNode(Const);
|
Const *cnst = makeNode(Const);
|
||||||
|
|
||||||
cnst->consttype = consttype;
|
cnst->consttype = consttype;
|
||||||
|
cnst->consttypmod = consttypmod;
|
||||||
cnst->constlen = constlen;
|
cnst->constlen = constlen;
|
||||||
cnst->constvalue = constvalue;
|
cnst->constvalue = constvalue;
|
||||||
cnst->constisnull = constisnull;
|
cnst->constisnull = constisnull;
|
||||||
@ -159,6 +161,8 @@ makeConst(Oid consttype,
|
|||||||
/*
|
/*
|
||||||
* makeNullConst -
|
* makeNullConst -
|
||||||
* creates a Const node representing a NULL of the specified type
|
* creates a Const node representing a NULL of the specified type
|
||||||
|
*
|
||||||
|
* Note: for all current uses, OK to set typmod of the Const to -1.
|
||||||
*/
|
*/
|
||||||
Const *
|
Const *
|
||||||
makeNullConst(Oid consttype)
|
makeNullConst(Oid consttype)
|
||||||
@ -168,6 +172,7 @@ makeNullConst(Oid consttype)
|
|||||||
|
|
||||||
get_typlenbyval(consttype, &typLen, &typByVal);
|
get_typlenbyval(consttype, &typLen, &typByVal);
|
||||||
return makeConst(consttype,
|
return makeConst(consttype,
|
||||||
|
-1,
|
||||||
(int) typLen,
|
(int) typLen,
|
||||||
(Datum) 0,
|
(Datum) 0,
|
||||||
true,
|
true,
|
||||||
@ -182,7 +187,8 @@ Node *
|
|||||||
makeBoolConst(bool value, bool isnull)
|
makeBoolConst(bool value, bool isnull)
|
||||||
{
|
{
|
||||||
/* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
|
/* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
|
||||||
return (Node *) makeConst(BOOLOID, 1, BoolGetDatum(value), isnull, true);
|
return (Node *) makeConst(BOOLOID, -1, 1,
|
||||||
|
BoolGetDatum(value), isnull, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.303 2007/03/13 00:33:40 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.304 2007/03/17 00:11:03 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Every node type that can appear in stored rules' parsetrees *must*
|
* Every node type that can appear in stored rules' parsetrees *must*
|
||||||
@ -685,6 +685,7 @@ _outConst(StringInfo str, Const *node)
|
|||||||
WRITE_NODE_TYPE("CONST");
|
WRITE_NODE_TYPE("CONST");
|
||||||
|
|
||||||
WRITE_OID_FIELD(consttype);
|
WRITE_OID_FIELD(consttype);
|
||||||
|
WRITE_INT_FIELD(consttypmod);
|
||||||
WRITE_INT_FIELD(constlen);
|
WRITE_INT_FIELD(constlen);
|
||||||
WRITE_BOOL_FIELD(constbyval);
|
WRITE_BOOL_FIELD(constbyval);
|
||||||
WRITE_BOOL_FIELD(constisnull);
|
WRITE_BOOL_FIELD(constisnull);
|
||||||
@ -725,9 +726,9 @@ _outArrayRef(StringInfo str, ArrayRef *node)
|
|||||||
{
|
{
|
||||||
WRITE_NODE_TYPE("ARRAYREF");
|
WRITE_NODE_TYPE("ARRAYREF");
|
||||||
|
|
||||||
WRITE_OID_FIELD(refrestype);
|
|
||||||
WRITE_OID_FIELD(refarraytype);
|
WRITE_OID_FIELD(refarraytype);
|
||||||
WRITE_OID_FIELD(refelemtype);
|
WRITE_OID_FIELD(refelemtype);
|
||||||
|
WRITE_INT_FIELD(reftypmod);
|
||||||
WRITE_NODE_FIELD(refupperindexpr);
|
WRITE_NODE_FIELD(refupperindexpr);
|
||||||
WRITE_NODE_FIELD(reflowerindexpr);
|
WRITE_NODE_FIELD(reflowerindexpr);
|
||||||
WRITE_NODE_FIELD(refexpr);
|
WRITE_NODE_FIELD(refexpr);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.203 2007/02/20 17:32:15 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.204 2007/03/17 00:11:04 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Path and Plan nodes do not have any readfuncs support, because we
|
* Path and Plan nodes do not have any readfuncs support, because we
|
||||||
@ -324,6 +324,7 @@ _readConst(void)
|
|||||||
READ_LOCALS(Const);
|
READ_LOCALS(Const);
|
||||||
|
|
||||||
READ_OID_FIELD(consttype);
|
READ_OID_FIELD(consttype);
|
||||||
|
READ_INT_FIELD(consttypmod);
|
||||||
READ_INT_FIELD(constlen);
|
READ_INT_FIELD(constlen);
|
||||||
READ_BOOL_FIELD(constbyval);
|
READ_BOOL_FIELD(constbyval);
|
||||||
READ_BOOL_FIELD(constisnull);
|
READ_BOOL_FIELD(constisnull);
|
||||||
@ -379,9 +380,9 @@ _readArrayRef(void)
|
|||||||
{
|
{
|
||||||
READ_LOCALS(ArrayRef);
|
READ_LOCALS(ArrayRef);
|
||||||
|
|
||||||
READ_OID_FIELD(refrestype);
|
|
||||||
READ_OID_FIELD(refarraytype);
|
READ_OID_FIELD(refarraytype);
|
||||||
READ_OID_FIELD(refelemtype);
|
READ_OID_FIELD(refelemtype);
|
||||||
|
READ_INT_FIELD(reftypmod);
|
||||||
READ_NODE_FIELD(refupperindexpr);
|
READ_NODE_FIELD(refupperindexpr);
|
||||||
READ_NODE_FIELD(reflowerindexpr);
|
READ_NODE_FIELD(reflowerindexpr);
|
||||||
READ_NODE_FIELD(refexpr);
|
READ_NODE_FIELD(refexpr);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 = make_opclause(opr1oid, BOOLOID, false,
|
||||||
(Expr *) leftop,
|
(Expr *) leftop,
|
||||||
(Expr *) makeConst(datatype, -1, opr1right,
|
(Expr *) makeConst(datatype, -1, -1, opr1right,
|
||||||
false, false));
|
false, false));
|
||||||
result = list_make1(make_restrictinfo(expr, true, false, false, NULL));
|
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 = make_opclause(opr2oid, BOOLOID, false,
|
||||||
(Expr *) leftop,
|
(Expr *) leftop,
|
||||||
(Expr *) makeConst(datatype, -1, opr2right,
|
(Expr *) makeConst(datatype, -1, -1, opr2right,
|
||||||
false, false));
|
false, false));
|
||||||
result = lappend(result,
|
result = lappend(result,
|
||||||
make_restrictinfo(expr, true, false, false, NULL));
|
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);
|
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);
|
conval, false, false);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 */
|
/* set up LIMIT 1 */
|
||||||
subparse->limitOffset = NULL;
|
subparse->limitOffset = NULL;
|
||||||
subparse->limitCount = (Node *) makeConst(INT8OID, sizeof(int64),
|
subparse->limitCount = (Node *) makeConst(INT8OID, -1, sizeof(int64),
|
||||||
Int64GetDatum(1),
|
Int64GetDatum(1),
|
||||||
false, false /* not by val */ );
|
false, false /* not by val */ );
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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)
|
if (!att_tup->attisdropped)
|
||||||
{
|
{
|
||||||
new_expr = (Node *) makeConst(atttype,
|
new_expr = (Node *) makeConst(atttype,
|
||||||
|
-1,
|
||||||
att_tup->attlen,
|
att_tup->attlen,
|
||||||
(Datum) 0,
|
(Datum) 0,
|
||||||
true, /* isnull */
|
true, /* isnull */
|
||||||
@ -296,6 +297,7 @@ expand_targetlist(List *tlist, int command_type,
|
|||||||
{
|
{
|
||||||
/* Insert NULL for dropped column */
|
/* Insert NULL for dropped column */
|
||||||
new_expr = (Node *) makeConst(INT4OID,
|
new_expr = (Node *) makeConst(INT4OID,
|
||||||
|
-1,
|
||||||
sizeof(int32),
|
sizeof(int32),
|
||||||
(Datum) 0,
|
(Datum) 0,
|
||||||
true, /* isnull */
|
true, /* isnull */
|
||||||
@ -315,6 +317,7 @@ expand_targetlist(List *tlist, int command_type,
|
|||||||
{
|
{
|
||||||
/* Insert NULL for dropped column */
|
/* Insert NULL for dropped column */
|
||||||
new_expr = (Node *) makeConst(INT4OID,
|
new_expr = (Node *) makeConst(INT4OID,
|
||||||
|
-1,
|
||||||
sizeof(int32),
|
sizeof(int32),
|
||||||
(Datum) 0,
|
(Datum) 0,
|
||||||
true, /* isnull */
|
true, /* isnull */
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 */
|
/* Add a resjunk flag column */
|
||||||
/* flag value is the given constant */
|
/* flag value is the given constant */
|
||||||
expr = (Node *) makeConst(INT4OID,
|
expr = (Node *) makeConst(INT4OID,
|
||||||
|
-1,
|
||||||
sizeof(int4),
|
sizeof(int4),
|
||||||
Int32GetDatum(flag),
|
Int32GetDatum(flag),
|
||||||
false,
|
false,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -82,10 +82,12 @@ static List *simplify_and_arguments(List *args,
|
|||||||
eval_const_expressions_context *context,
|
eval_const_expressions_context *context,
|
||||||
bool *haveNull, bool *forceFalse);
|
bool *haveNull, bool *forceFalse);
|
||||||
static Expr *simplify_boolean_equality(List *args);
|
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,
|
bool allow_inline,
|
||||||
eval_const_expressions_context *context);
|
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,
|
HeapTuple func_tuple,
|
||||||
eval_const_expressions_context *context);
|
eval_const_expressions_context *context);
|
||||||
static Expr *inline_function(Oid funcid, Oid result_type, List *args,
|
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,
|
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 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;
|
return true;
|
||||||
if (IsA(node, CaseExpr))
|
if (IsA(node, CaseExpr))
|
||||||
return true;
|
return true;
|
||||||
if (IsA(node, CaseWhen))
|
|
||||||
return true;
|
|
||||||
if (IsA(node, ArrayExpr))
|
if (IsA(node, ArrayExpr))
|
||||||
return true;
|
return true;
|
||||||
if (IsA(node, RowExpr))
|
if (IsA(node, RowExpr))
|
||||||
@ -1654,6 +1654,7 @@ eval_const_expressions_mutator(Node *node,
|
|||||||
else
|
else
|
||||||
pval = datumCopy(prm->value, typByVal, typLen);
|
pval = datumCopy(prm->value, typByVal, typLen);
|
||||||
return (Node *) makeConst(param->paramtype,
|
return (Node *) makeConst(param->paramtype,
|
||||||
|
param->paramtypmod,
|
||||||
(int) typLen,
|
(int) typLen,
|
||||||
pval,
|
pval,
|
||||||
prm->isnull,
|
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
|
* 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);
|
true, context);
|
||||||
if (simple) /* successfully simplified it */
|
if (simple) /* successfully simplified it */
|
||||||
return (Node *) simple;
|
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
|
* Code for op/func reduction is pretty bulky, so split it out as a
|
||||||
* separate function.
|
* separate function.
|
||||||
*/
|
*/
|
||||||
simple = simplify_function(expr->opfuncid, expr->opresulttype, args,
|
simple = simplify_function(expr->opfuncid,
|
||||||
|
expr->opresulttype, -1,
|
||||||
|
args,
|
||||||
true, context);
|
true, context);
|
||||||
if (simple) /* successfully simplified it */
|
if (simple) /* successfully simplified it */
|
||||||
return (Node *) simple;
|
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
|
* Code for op/func reduction is pretty bulky, so split it out as
|
||||||
* a separate function.
|
* a separate function.
|
||||||
*/
|
*/
|
||||||
simple = simplify_function(expr->opfuncid, expr->opresulttype,
|
simple = simplify_function(expr->opfuncid,
|
||||||
args, false, context);
|
expr->opresulttype, -1,
|
||||||
|
args,
|
||||||
|
false, context);
|
||||||
if (simple) /* successfully simplified it */
|
if (simple) /* successfully simplified it */
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -1961,12 +1970,7 @@ eval_const_expressions_mutator(Node *node,
|
|||||||
Const *con = (Const *) arg;
|
Const *con = (Const *) arg;
|
||||||
|
|
||||||
con->consttype = relabel->resulttype;
|
con->consttype = relabel->resulttype;
|
||||||
|
con->consttypmod = relabel->resulttypmod;
|
||||||
/*
|
|
||||||
* 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;
|
return (Node *) con;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2134,7 +2138,8 @@ eval_const_expressions_mutator(Node *node,
|
|||||||
|
|
||||||
if (all_const)
|
if (all_const)
|
||||||
return (Node *) evaluate_expr((Expr *) newarray,
|
return (Node *) evaluate_expr((Expr *) newarray,
|
||||||
newarray->array_typeid);
|
newarray->array_typeid,
|
||||||
|
exprTypmod(node));
|
||||||
|
|
||||||
return (Node *) newarray;
|
return (Node *) newarray;
|
||||||
}
|
}
|
||||||
@ -2637,14 +2642,15 @@ simplify_boolean_equality(List *args)
|
|||||||
* (which might originally have been an operator; we don't care)
|
* (which might originally have been an operator; we don't care)
|
||||||
*
|
*
|
||||||
* Inputs are the function OID, actual result type OID (which is needed for
|
* 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.
|
* also the context data for eval_const_expressions.
|
||||||
*
|
*
|
||||||
* Returns a simplified expression if successful, or NULL if cannot
|
* Returns a simplified expression if successful, or NULL if cannot
|
||||||
* simplify the function call.
|
* simplify the function call.
|
||||||
*/
|
*/
|
||||||
static Expr *
|
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,
|
bool allow_inline,
|
||||||
eval_const_expressions_context *context)
|
eval_const_expressions_context *context)
|
||||||
{
|
{
|
||||||
@ -2665,7 +2671,7 @@ simplify_function(Oid funcid, Oid result_type, List *args,
|
|||||||
if (!HeapTupleIsValid(func_tuple))
|
if (!HeapTupleIsValid(func_tuple))
|
||||||
elog(ERROR, "cache lookup failed for function %u", funcid);
|
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);
|
func_tuple, context);
|
||||||
|
|
||||||
if (!newexpr && allow_inline)
|
if (!newexpr && allow_inline)
|
||||||
@ -2689,7 +2695,7 @@ simplify_function(Oid funcid, Oid result_type, List *args,
|
|||||||
* simplify the function.
|
* simplify the function.
|
||||||
*/
|
*/
|
||||||
static Expr *
|
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,
|
HeapTuple func_tuple,
|
||||||
eval_const_expressions_context *context)
|
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->funcformat = COERCE_DONTCARE; /* doesn't matter */
|
||||||
newexpr->args = args;
|
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.
|
* code and ensure we get the same result as the executor would get.
|
||||||
*/
|
*/
|
||||||
static Expr *
|
static Expr *
|
||||||
evaluate_expr(Expr *expr, Oid result_type)
|
evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod)
|
||||||
{
|
{
|
||||||
EState *estate;
|
EState *estate;
|
||||||
ExprState *exprstate;
|
ExprState *exprstate;
|
||||||
@ -3184,7 +3190,7 @@ evaluate_expr(Expr *expr, Oid result_type)
|
|||||||
/*
|
/*
|
||||||
* Make the constant result node.
|
* Make the constant result node.
|
||||||
*/
|
*/
|
||||||
return (Expr *) makeConst(result_type, resultTypLen,
|
return (Expr *) makeConst(result_type, result_typmod, resultTypLen,
|
||||||
const_val, const_is_null,
|
const_val, const_is_null,
|
||||||
resultTypByVal);
|
resultTypByVal);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 */
|
/* Set up a dummy Const node to hold the per-element values */
|
||||||
state->constexpr.xpr.type = T_Const;
|
state->constexpr.xpr.type = T_Const;
|
||||||
state->constexpr.consttype = ARR_ELEMTYPE(arrayval);
|
state->constexpr.consttype = ARR_ELEMTYPE(arrayval);
|
||||||
|
state->constexpr.consttypmod = -1;
|
||||||
state->constexpr.constlen = elmlen;
|
state->constexpr.constlen = elmlen;
|
||||||
state->constexpr.constbyval = elmbyval;
|
state->constexpr.constbyval = elmbyval;
|
||||||
lsecond(state->opexpr.args) = &state->constexpr;
|
lsecond(state->opexpr.args) = &state->constexpr;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.150 2007/01/05 22:19:34 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.151 2007/03/17 00:11:04 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -186,6 +186,7 @@ coerce_type(ParseState *pstate, Node *node,
|
|||||||
targetType = typeidType(baseTypeId);
|
targetType = typeidType(baseTypeId);
|
||||||
|
|
||||||
newcon->consttype = baseTypeId;
|
newcon->consttype = baseTypeId;
|
||||||
|
newcon->consttypmod = -1;
|
||||||
newcon->constlen = typeLen(targetType);
|
newcon->constlen = typeLen(targetType);
|
||||||
newcon->constbyval = typeByVal(targetType);
|
newcon->constbyval = typeByVal(targetType);
|
||||||
newcon->constisnull = con->constisnull;
|
newcon->constisnull = con->constisnull;
|
||||||
@ -661,6 +662,7 @@ build_coercion_expression(Node *node, Oid funcId,
|
|||||||
{
|
{
|
||||||
/* Pass target typmod as an int4 constant */
|
/* Pass target typmod as an int4 constant */
|
||||||
cons = makeConst(INT4OID,
|
cons = makeConst(INT4OID,
|
||||||
|
-1,
|
||||||
sizeof(int32),
|
sizeof(int32),
|
||||||
Int32GetDatum(targetTypMod),
|
Int32GetDatum(targetTypMod),
|
||||||
false,
|
false,
|
||||||
@ -673,6 +675,7 @@ build_coercion_expression(Node *node, Oid funcId,
|
|||||||
{
|
{
|
||||||
/* Pass it a boolean isExplicit parameter, too */
|
/* Pass it a boolean isExplicit parameter, too */
|
||||||
cons = makeConst(BOOLOID,
|
cons = makeConst(BOOLOID,
|
||||||
|
-1,
|
||||||
sizeof(bool),
|
sizeof(bool),
|
||||||
BoolGetDatum(isExplicit),
|
BoolGetDatum(isExplicit),
|
||||||
false,
|
false,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.212 2007/02/22 22:00:25 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.213 2007/03/17 00:11:04 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -312,7 +312,7 @@ transformIndirection(ParseState *pstate, Node *basenode, List *indirection)
|
|||||||
result,
|
result,
|
||||||
exprType(result),
|
exprType(result),
|
||||||
InvalidOid,
|
InvalidOid,
|
||||||
-1,
|
exprTypmod(result),
|
||||||
subscripts,
|
subscripts,
|
||||||
NULL);
|
NULL);
|
||||||
subscripts = NIL;
|
subscripts = NIL;
|
||||||
@ -330,7 +330,7 @@ transformIndirection(ParseState *pstate, Node *basenode, List *indirection)
|
|||||||
result,
|
result,
|
||||||
exprType(result),
|
exprType(result),
|
||||||
InvalidOid,
|
InvalidOid,
|
||||||
-1,
|
exprTypmod(result),
|
||||||
subscripts,
|
subscripts,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
@ -1705,7 +1705,15 @@ exprType(Node *expr)
|
|||||||
type = ((Aggref *) expr)->aggtype;
|
type = ((Aggref *) expr)->aggtype;
|
||||||
break;
|
break;
|
||||||
case T_ArrayRef:
|
case T_ArrayRef:
|
||||||
type = ((ArrayRef *) expr)->refrestype;
|
{
|
||||||
|
ArrayRef *arrayref = (ArrayRef *) expr;
|
||||||
|
|
||||||
|
/* slice and/or store operations yield the array type */
|
||||||
|
if (arrayref->reflowerindexpr || arrayref->refassgnexpr)
|
||||||
|
type = arrayref->refarraytype;
|
||||||
|
else
|
||||||
|
type = arrayref->refelemtype;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case T_FuncExpr:
|
case T_FuncExpr:
|
||||||
type = ((FuncExpr *) expr)->funcresulttype;
|
type = ((FuncExpr *) expr)->funcresulttype;
|
||||||
@ -1802,9 +1810,6 @@ exprType(Node *expr)
|
|||||||
case T_CaseExpr:
|
case T_CaseExpr:
|
||||||
type = ((CaseExpr *) expr)->casetype;
|
type = ((CaseExpr *) expr)->casetype;
|
||||||
break;
|
break;
|
||||||
case T_CaseWhen:
|
|
||||||
type = exprType((Node *) ((CaseWhen *) expr)->result);
|
|
||||||
break;
|
|
||||||
case T_CaseTestExpr:
|
case T_CaseTestExpr:
|
||||||
type = ((CaseTestExpr *) expr)->typeId;
|
type = ((CaseTestExpr *) expr)->typeId;
|
||||||
break;
|
break;
|
||||||
@ -1872,8 +1877,13 @@ exprTypmod(Node *expr)
|
|||||||
{
|
{
|
||||||
case T_Var:
|
case T_Var:
|
||||||
return ((Var *) expr)->vartypmod;
|
return ((Var *) expr)->vartypmod;
|
||||||
|
case T_Const:
|
||||||
|
return ((Const *) expr)->consttypmod;
|
||||||
case T_Param:
|
case T_Param:
|
||||||
return ((Param *) expr)->paramtypmod;
|
return ((Param *) expr)->paramtypmod;
|
||||||
|
case T_ArrayRef:
|
||||||
|
/* typmod is the same for array or element */
|
||||||
|
return ((ArrayRef *) expr)->reftypmod;
|
||||||
case T_FuncExpr:
|
case T_FuncExpr:
|
||||||
{
|
{
|
||||||
int32 coercedTypmod;
|
int32 coercedTypmod;
|
||||||
@ -1883,6 +1893,27 @@ exprTypmod(Node *expr)
|
|||||||
return coercedTypmod;
|
return coercedTypmod;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case T_SubLink:
|
||||||
|
{
|
||||||
|
SubLink *sublink = (SubLink *) expr;
|
||||||
|
|
||||||
|
if (sublink->subLinkType == EXPR_SUBLINK ||
|
||||||
|
sublink->subLinkType == ARRAY_SUBLINK)
|
||||||
|
{
|
||||||
|
/* get the typmod of the subselect's first target column */
|
||||||
|
Query *qtree = (Query *) sublink->subselect;
|
||||||
|
TargetEntry *tent;
|
||||||
|
|
||||||
|
if (!qtree || !IsA(qtree, Query))
|
||||||
|
elog(ERROR, "cannot get type for untransformed sublink");
|
||||||
|
tent = (TargetEntry *) linitial(qtree->targetList);
|
||||||
|
Assert(IsA(tent, TargetEntry));
|
||||||
|
Assert(!tent->resjunk);
|
||||||
|
return exprTypmod((Node *) tent->expr);
|
||||||
|
/* note we don't need to care if it's an array */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case T_FieldSelect:
|
case T_FieldSelect:
|
||||||
return ((FieldSelect *) expr)->resulttypmod;
|
return ((FieldSelect *) expr)->resulttypmod;
|
||||||
case T_RelabelType:
|
case T_RelabelType:
|
||||||
@ -1920,6 +1951,34 @@ exprTypmod(Node *expr)
|
|||||||
break;
|
break;
|
||||||
case T_CaseTestExpr:
|
case T_CaseTestExpr:
|
||||||
return ((CaseTestExpr *) expr)->typeMod;
|
return ((CaseTestExpr *) expr)->typeMod;
|
||||||
|
case T_ArrayExpr:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If all the elements agree on type/typmod, return that
|
||||||
|
* typmod, else use -1
|
||||||
|
*/
|
||||||
|
ArrayExpr *arrayexpr = (ArrayExpr *) expr;
|
||||||
|
Oid arraytype = arrayexpr->array_typeid;
|
||||||
|
int32 typmod;
|
||||||
|
ListCell *elem;
|
||||||
|
|
||||||
|
if (arrayexpr->elements == NIL)
|
||||||
|
return -1;
|
||||||
|
typmod = exprTypmod((Node *) linitial(arrayexpr->elements));
|
||||||
|
if (typmod < 0)
|
||||||
|
return -1; /* no point in trying harder */
|
||||||
|
foreach(elem, arrayexpr->elements)
|
||||||
|
{
|
||||||
|
Node *e = (Node *) lfirst(elem);
|
||||||
|
|
||||||
|
if (exprType(e) != arraytype)
|
||||||
|
return -1;
|
||||||
|
if (exprTypmod(e) != typmod)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return typmod;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case T_CoalesceExpr:
|
case T_CoalesceExpr:
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.96 2007/01/05 22:19:34 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.97 2007/03/17 00:11:04 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -153,7 +153,8 @@ transformArrayType(Oid arrayType)
|
|||||||
* arrayType OID of array's datatype (should match type of arrayBase)
|
* arrayType OID of array's datatype (should match type of arrayBase)
|
||||||
* elementType OID of array's element type (fetch with transformArrayType,
|
* elementType OID of array's element type (fetch with transformArrayType,
|
||||||
* or pass InvalidOid to do it here)
|
* or pass InvalidOid to do it here)
|
||||||
* elementTypMod typmod to be applied to array elements (if storing)
|
* elementTypMod typmod to be applied to array elements (if storing) or of
|
||||||
|
* the source array (if fetching)
|
||||||
* indirection Untransformed list of subscripts (must not be NIL)
|
* indirection Untransformed list of subscripts (must not be NIL)
|
||||||
* assignFrom NULL for array fetch, else transformed expression for source.
|
* assignFrom NULL for array fetch, else transformed expression for source.
|
||||||
*/
|
*/
|
||||||
@ -166,7 +167,6 @@ transformArraySubscripts(ParseState *pstate,
|
|||||||
List *indirection,
|
List *indirection,
|
||||||
Node *assignFrom)
|
Node *assignFrom)
|
||||||
{
|
{
|
||||||
Oid resultType;
|
|
||||||
bool isSlice = false;
|
bool isSlice = false;
|
||||||
List *upperIndexpr = NIL;
|
List *upperIndexpr = NIL;
|
||||||
List *lowerIndexpr = NIL;
|
List *lowerIndexpr = NIL;
|
||||||
@ -196,16 +196,6 @@ transformArraySubscripts(ParseState *pstate,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The type represented by the subscript expression is the element type if
|
|
||||||
* we are fetching a single element, but it is the same as the array type
|
|
||||||
* if we are fetching a slice or storing.
|
|
||||||
*/
|
|
||||||
if (isSlice || assignFrom != NULL)
|
|
||||||
resultType = arrayType;
|
|
||||||
else
|
|
||||||
resultType = elementType;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transform the subscript expressions.
|
* Transform the subscript expressions.
|
||||||
*/
|
*/
|
||||||
@ -235,6 +225,7 @@ transformArraySubscripts(ParseState *pstate,
|
|||||||
{
|
{
|
||||||
/* Make a constant 1 */
|
/* Make a constant 1 */
|
||||||
subexpr = (Node *) makeConst(INT4OID,
|
subexpr = (Node *) makeConst(INT4OID,
|
||||||
|
-1,
|
||||||
sizeof(int32),
|
sizeof(int32),
|
||||||
Int32GetDatum(1),
|
Int32GetDatum(1),
|
||||||
false,
|
false,
|
||||||
@ -284,9 +275,9 @@ transformArraySubscripts(ParseState *pstate,
|
|||||||
* Ready to build the ArrayRef node.
|
* Ready to build the ArrayRef node.
|
||||||
*/
|
*/
|
||||||
aref = makeNode(ArrayRef);
|
aref = makeNode(ArrayRef);
|
||||||
aref->refrestype = resultType;
|
|
||||||
aref->refarraytype = arrayType;
|
aref->refarraytype = arrayType;
|
||||||
aref->refelemtype = elementType;
|
aref->refelemtype = elementType;
|
||||||
|
aref->reftypmod = elementTypMod;
|
||||||
aref->refupperindexpr = upperIndexpr;
|
aref->refupperindexpr = upperIndexpr;
|
||||||
aref->reflowerindexpr = lowerIndexpr;
|
aref->reflowerindexpr = lowerIndexpr;
|
||||||
aref->refexpr = (Expr *) arrayBase;
|
aref->refexpr = (Expr *) arrayBase;
|
||||||
@ -399,6 +390,7 @@ make_const(Value *value)
|
|||||||
case T_Null:
|
case T_Null:
|
||||||
/* return a null const */
|
/* return a null const */
|
||||||
con = makeConst(UNKNOWNOID,
|
con = makeConst(UNKNOWNOID,
|
||||||
|
-1,
|
||||||
-2,
|
-2,
|
||||||
(Datum) 0,
|
(Datum) 0,
|
||||||
true,
|
true,
|
||||||
@ -411,6 +403,7 @@ make_const(Value *value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
con = makeConst(typeid,
|
con = makeConst(typeid,
|
||||||
|
-1, /* typmod -1 is OK for all cases */
|
||||||
typelen,
|
typelen,
|
||||||
val,
|
val,
|
||||||
false,
|
false,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.171 2007/03/01 18:50:28 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.172 2007/03/17 00:11:04 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -643,6 +643,7 @@ rewriteTargetList(Query *parsetree, Relation target_relation,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
new_expr = (Node *) makeConst(att_tup->atttypid,
|
new_expr = (Node *) makeConst(att_tup->atttypid,
|
||||||
|
-1,
|
||||||
att_tup->attlen,
|
att_tup->attlen,
|
||||||
(Datum) 0,
|
(Datum) 0,
|
||||||
true, /* isnull */
|
true, /* isnull */
|
||||||
@ -981,6 +982,7 @@ rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation, List *attrnos)
|
|||||||
if (!new_expr)
|
if (!new_expr)
|
||||||
{
|
{
|
||||||
new_expr = (Node *) makeConst(att_tup->atttypid,
|
new_expr = (Node *) makeConst(att_tup->atttypid,
|
||||||
|
-1,
|
||||||
att_tup->attlen,
|
att_tup->attlen,
|
||||||
(Datum) 0,
|
(Datum) 0,
|
||||||
true, /* isnull */
|
true, /* isnull */
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.253 2007/03/15 23:12:06 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.254 2007/03/17 00:11:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -170,7 +170,11 @@ static void get_oper_expr(OpExpr *expr, deparse_context *context);
|
|||||||
static void get_func_expr(FuncExpr *expr, deparse_context *context,
|
static void get_func_expr(FuncExpr *expr, deparse_context *context,
|
||||||
bool showimplicit);
|
bool showimplicit);
|
||||||
static void get_agg_expr(Aggref *aggref, deparse_context *context);
|
static void get_agg_expr(Aggref *aggref, deparse_context *context);
|
||||||
static void get_const_expr(Const *constval, deparse_context *context);
|
static void get_coercion_expr(Node *arg, deparse_context *context,
|
||||||
|
Oid resulttype, int32 resulttypmod,
|
||||||
|
Node *parentNode);
|
||||||
|
static void get_const_expr(Const *constval, deparse_context *context,
|
||||||
|
bool showtype);
|
||||||
static void get_sublink_expr(SubLink *sublink, deparse_context *context);
|
static void get_sublink_expr(SubLink *sublink, deparse_context *context);
|
||||||
static void get_from_clause(Query *query, const char *prefix,
|
static void get_from_clause(Query *query, const char *prefix,
|
||||||
deparse_context *context);
|
deparse_context *context);
|
||||||
@ -3364,7 +3368,7 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_Const:
|
case T_Const:
|
||||||
get_const_expr((Const *) node, context);
|
get_const_expr((Const *) node, context, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_Param:
|
case T_Param:
|
||||||
@ -3576,14 +3580,10 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!PRETTY_PAREN(context))
|
get_coercion_expr(arg, context,
|
||||||
appendStringInfoChar(buf, '(');
|
relabel->resulttype,
|
||||||
get_rule_expr_paren(arg, context, false, node);
|
relabel->resulttypmod,
|
||||||
if (!PRETTY_PAREN(context))
|
node);
|
||||||
appendStringInfoChar(buf, ')');
|
|
||||||
appendStringInfo(buf, "::%s",
|
|
||||||
format_type_with_typemod(relabel->resulttype,
|
|
||||||
relabel->resulttypmod));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3601,13 +3601,9 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!PRETTY_PAREN(context))
|
get_coercion_expr(arg, context,
|
||||||
appendStringInfoChar(buf, '(');
|
convert->resulttype, -1,
|
||||||
get_rule_expr_paren(arg, context, false, node);
|
node);
|
||||||
if (!PRETTY_PAREN(context))
|
|
||||||
appendStringInfoChar(buf, ')');
|
|
||||||
appendStringInfo(buf, "::%s",
|
|
||||||
format_type_with_typemod(convert->resulttype, -1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4070,14 +4066,10 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!PRETTY_PAREN(context))
|
get_coercion_expr(arg, context,
|
||||||
appendStringInfoChar(buf, '(');
|
ctest->resulttype,
|
||||||
get_rule_expr_paren(arg, context, false, node);
|
ctest->resulttypmod,
|
||||||
if (!PRETTY_PAREN(context))
|
node);
|
||||||
appendStringInfoChar(buf, ')');
|
|
||||||
appendStringInfo(buf, "::%s",
|
|
||||||
format_type_with_typemod(ctest->resulttype,
|
|
||||||
ctest->resulttypmod));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4213,13 +4205,9 @@ get_func_expr(FuncExpr *expr, deparse_context *context,
|
|||||||
/* Get the typmod if this is a length-coercion function */
|
/* Get the typmod if this is a length-coercion function */
|
||||||
(void) exprIsLengthCoercion((Node *) expr, &coercedTypmod);
|
(void) exprIsLengthCoercion((Node *) expr, &coercedTypmod);
|
||||||
|
|
||||||
if (!PRETTY_PAREN(context))
|
get_coercion_expr(arg, context,
|
||||||
appendStringInfoChar(buf, '(');
|
rettype, coercedTypmod,
|
||||||
get_rule_expr_paren(arg, context, false, (Node *) expr);
|
(Node *) expr);
|
||||||
if (!PRETTY_PAREN(context))
|
|
||||||
appendStringInfoChar(buf, ')');
|
|
||||||
appendStringInfo(buf, "::%s",
|
|
||||||
format_type_with_typemod(rettype, coercedTypmod));
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4278,15 +4266,58 @@ get_agg_expr(Aggref *aggref, deparse_context *context)
|
|||||||
appendStringInfoChar(buf, ')');
|
appendStringInfoChar(buf, ')');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* get_coercion_expr
|
||||||
|
*
|
||||||
|
* Make a string representation of a value coerced to a specific type
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
get_coercion_expr(Node *arg, deparse_context *context,
|
||||||
|
Oid resulttype, int32 resulttypmod,
|
||||||
|
Node *parentNode)
|
||||||
|
{
|
||||||
|
StringInfo buf = context->buf;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since parse_coerce.c doesn't immediately collapse application of
|
||||||
|
* length-coercion functions to constants, what we'll typically see
|
||||||
|
* in such cases is a Const with typmod -1 and a length-coercion
|
||||||
|
* function right above it. Avoid generating redundant output.
|
||||||
|
* However, beware of suppressing casts when the user actually wrote
|
||||||
|
* something like 'foo'::text::char(3).
|
||||||
|
*/
|
||||||
|
if (arg && IsA(arg, Const) &&
|
||||||
|
((Const *) arg)->consttype == resulttype &&
|
||||||
|
((Const *) arg)->consttypmod == -1)
|
||||||
|
{
|
||||||
|
/* Show the constant without normal ::typename decoration */
|
||||||
|
get_const_expr((Const *) arg, context, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!PRETTY_PAREN(context))
|
||||||
|
appendStringInfoChar(buf, '(');
|
||||||
|
get_rule_expr_paren(arg, context, false, parentNode);
|
||||||
|
if (!PRETTY_PAREN(context))
|
||||||
|
appendStringInfoChar(buf, ')');
|
||||||
|
}
|
||||||
|
appendStringInfo(buf, "::%s",
|
||||||
|
format_type_with_typemod(resulttype, resulttypmod));
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* get_const_expr
|
* get_const_expr
|
||||||
*
|
*
|
||||||
* Make a string representation of a Const
|
* Make a string representation of a Const
|
||||||
|
*
|
||||||
|
* Note: if showtype is false, the Const is the direct argument of a coercion
|
||||||
|
* operation with the same target type, and so we should suppress "::typename"
|
||||||
|
* to avoid redundant output.
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
get_const_expr(Const *constval, deparse_context *context)
|
get_const_expr(Const *constval, deparse_context *context, bool showtype)
|
||||||
{
|
{
|
||||||
StringInfo buf = context->buf;
|
StringInfo buf = context->buf;
|
||||||
Oid typoutput;
|
Oid typoutput;
|
||||||
@ -4302,8 +4333,11 @@ get_const_expr(Const *constval, deparse_context *context)
|
|||||||
* Always label the type of a NULL constant to prevent misdecisions
|
* Always label the type of a NULL constant to prevent misdecisions
|
||||||
* about type when reparsing.
|
* about type when reparsing.
|
||||||
*/
|
*/
|
||||||
appendStringInfo(buf, "NULL::%s",
|
appendStringInfo(buf, "NULL");
|
||||||
format_type_with_typemod(constval->consttype, -1));
|
if (showtype)
|
||||||
|
appendStringInfo(buf, "::%s",
|
||||||
|
format_type_with_typemod(constval->consttype,
|
||||||
|
constval->consttypmod));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4376,6 +4410,9 @@ get_const_expr(Const *constval, deparse_context *context)
|
|||||||
|
|
||||||
pfree(extval);
|
pfree(extval);
|
||||||
|
|
||||||
|
if (!showtype)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Append ::typename unless the constant will be implicitly typed as the
|
* Append ::typename unless the constant will be implicitly typed as the
|
||||||
* right type when it is read in. XXX this code has to be kept in sync
|
* right type when it is read in. XXX this code has to be kept in sync
|
||||||
@ -4399,7 +4436,8 @@ get_const_expr(Const *constval, deparse_context *context)
|
|||||||
}
|
}
|
||||||
if (needlabel)
|
if (needlabel)
|
||||||
appendStringInfo(buf, "::%s",
|
appendStringInfo(buf, "::%s",
|
||||||
format_type_with_typemod(constval->consttype, -1));
|
format_type_with_typemod(constval->consttype,
|
||||||
|
constval->consttypmod));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.228 2007/02/27 23:48:09 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.229 2007/03/17 00:11:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1599,6 +1599,7 @@ scalararraysel(PlannerInfo *root,
|
|||||||
|
|
||||||
args = list_make2(leftop,
|
args = list_make2(leftop,
|
||||||
makeConst(nominal_element_type,
|
makeConst(nominal_element_type,
|
||||||
|
-1,
|
||||||
elmlen,
|
elmlen,
|
||||||
elem_values[i],
|
elem_values[i],
|
||||||
elem_nulls[i],
|
elem_nulls[i],
|
||||||
@ -4717,7 +4718,8 @@ string_to_const(const char *str, Oid datatype)
|
|||||||
{
|
{
|
||||||
Datum conval = string_to_datum(str, 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);
|
conval, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4734,7 +4736,7 @@ string_to_bytea_const(const char *str, size_t str_len)
|
|||||||
SET_VARSIZE(bstr, VARHDRSZ + str_len);
|
SET_VARSIZE(bstr, VARHDRSZ + str_len);
|
||||||
conval = PointerGetDatum(bstr);
|
conval = PointerGetDatum(bstr);
|
||||||
|
|
||||||
return makeConst(BYTEAOID, -1, conval, false, false);
|
return makeConst(BYTEAOID, -1, -1, conval, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
|
3
src/backend/utils/cache/lsyscache.c
vendored
3
src/backend/utils/cache/lsyscache.c
vendored
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.148 2007/02/14 01:58:57 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.149 2007/03/17 00:11:05 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Eventually, the index information should go through here, too.
|
* Eventually, the index information should go through here, too.
|
||||||
@ -1964,6 +1964,7 @@ get_typdefault(Oid typid)
|
|||||||
getTypeIOParam(typeTuple), -1);
|
getTypeIOParam(typeTuple), -1);
|
||||||
/* Build a Const node containing the value */
|
/* Build a Const node containing the value */
|
||||||
expr = (Node *) makeConst(typid,
|
expr = (Node *) makeConst(typid,
|
||||||
|
-1,
|
||||||
type->typlen,
|
type->typlen,
|
||||||
datum,
|
datum,
|
||||||
false,
|
false,
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.390 2007/03/16 17:57:36 mha Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.391 2007/03/17 00:11:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200703161
|
#define CATALOG_VERSION_NO 200703162
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.57 2007/01/05 22:19:55 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.58 2007/03/17 00:11:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -37,6 +37,7 @@ extern TargetEntry *makeTargetEntry(Expr *expr,
|
|||||||
extern TargetEntry *flatCopyTargetEntry(TargetEntry *src_tle);
|
extern TargetEntry *flatCopyTargetEntry(TargetEntry *src_tle);
|
||||||
|
|
||||||
extern Const *makeConst(Oid consttype,
|
extern Const *makeConst(Oid consttype,
|
||||||
|
int32 consttypmod,
|
||||||
int constlen,
|
int constlen,
|
||||||
Datum constvalue,
|
Datum constvalue,
|
||||||
bool constisnull,
|
bool constisnull,
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.127 2007/02/22 22:00:25 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.128 2007/03/17 00:11:05 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -154,7 +154,8 @@ typedef struct Var
|
|||||||
typedef struct Const
|
typedef struct Const
|
||||||
{
|
{
|
||||||
Expr xpr;
|
Expr xpr;
|
||||||
Oid consttype; /* PG_TYPE OID of the constant's datatype */
|
Oid consttype; /* pg_type OID of the constant's datatype */
|
||||||
|
int32 consttypmod; /* typmod value, if any */
|
||||||
int constlen; /* typlen of the constant's datatype */
|
int constlen; /* typlen of the constant's datatype */
|
||||||
Datum constvalue; /* the constant's value */
|
Datum constvalue; /* the constant's value */
|
||||||
bool constisnull; /* whether the constant is null (if true,
|
bool constisnull; /* whether the constant is null (if true,
|
||||||
@ -236,17 +237,17 @@ typedef struct Aggref
|
|||||||
* reflowerindexpr must be the same length as refupperindexpr when it
|
* reflowerindexpr must be the same length as refupperindexpr when it
|
||||||
* is not NIL.
|
* is not NIL.
|
||||||
*
|
*
|
||||||
* Note: refrestype is NOT the element type, but the array type,
|
* Note: the result datatype is the element type when fetching a single
|
||||||
* when doing subarray fetch or either type of store.
|
* element; but it is the array type when doing subarray fetch or either
|
||||||
|
* type of store.
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
typedef struct ArrayRef
|
typedef struct ArrayRef
|
||||||
{
|
{
|
||||||
Expr xpr;
|
Expr xpr;
|
||||||
Oid refrestype; /* type of the result of the ArrayRef
|
|
||||||
* operation */
|
|
||||||
Oid refarraytype; /* type of the array proper */
|
Oid refarraytype; /* type of the array proper */
|
||||||
Oid refelemtype; /* type of the array elements */
|
Oid refelemtype; /* type of the array elements */
|
||||||
|
int32 reftypmod; /* typmod of the array (and elements too) */
|
||||||
List *refupperindexpr;/* expressions that evaluate to upper array
|
List *refupperindexpr;/* expressions that evaluate to upper array
|
||||||
* indexes */
|
* indexes */
|
||||||
List *reflowerindexpr;/* expressions that evaluate to lower array
|
List *reflowerindexpr;/* expressions that evaluate to lower array
|
||||||
|
Loading…
Reference in New Issue
Block a user