Make eval_const_expressions() preserve typmod when simplifying something like

null::char(3) to a simple Const node.  (It already worked for non-null values,
but not when we skipped evaluation of a strict coercion function.)  This
prevents loss of typmod knowledge in situations such as exhibited in bug
#3598.  Unfortunately there seems no good way to fix that bug in 8.1 and 8.2,
because they simply don't carry a typmod for a plain Const node.

In passing I made all the other callers of makeNullConst supply "real" typmod
values too, though I think it probably doesn't matter anywhere else.
This commit is contained in:
Tom Lane 2007-09-06 17:31:58 +00:00
parent 190df8a4cf
commit f8942f4a15
10 changed files with 31 additions and 26 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.231 2007/08/21 01:11:14 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.232 2007/09/06 17:31:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -3179,12 +3179,15 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
if (!defval && GetDomainConstraints(typeOid) != NIL) if (!defval && GetDomainConstraints(typeOid) != NIL)
{ {
Oid basetype = getBaseType(typeOid); Oid baseTypeId;
int32 baseTypeMod;
defval = (Expr *) makeNullConst(basetype); baseTypeMod = typmod;
baseTypeId = getBaseTypeAndTypmod(typeOid, &baseTypeMod);
defval = (Expr *) makeNullConst(baseTypeId, baseTypeMod);
defval = (Expr *) coerce_to_target_type(NULL, defval = (Expr *) coerce_to_target_type(NULL,
(Node *) defval, (Node *) defval,
basetype, baseTypeId,
typeOid, typeOid,
typmod, typmod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.221 2007/08/31 18:33:40 tgl Exp $ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.222 2007/09/06 17:31:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -4159,7 +4159,7 @@ ExecInitExpr(Expr *node, PlanState *parent)
* don't really care what type of NULL it is, so * don't really care what type of NULL it is, so
* always make an int4 NULL. * always make an int4 NULL.
*/ */
e = (Expr *) makeNullConst(INT4OID); e = (Expr *) makeNullConst(INT4OID, -1);
} }
estate = ExecInitExpr(e, parent); estate = ExecInitExpr(e, parent);
outlist = lappend(outlist, estate); outlist = lappend(outlist, estate);

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.56 2007/06/23 22:12:50 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.57 2007/09/06 17:31:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -174,19 +174,20 @@ 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/typmod
* *
* Note: for all current uses, OK to set typmod of the Const to -1. * This is a convenience routine that just saves a lookup of the type's
* storage properties.
*/ */
Const * Const *
makeNullConst(Oid consttype) makeNullConst(Oid consttype, int32 consttypmod)
{ {
int16 typLen; int16 typLen;
bool typByVal; bool typByVal;
get_typlenbyval(consttype, &typLen, &typByVal); get_typlenbyval(consttype, &typLen, &typByVal);
return makeConst(consttype, return makeConst(consttype,
-1, consttypmod,
(int) typLen, (int) typLen,
(Datum) 0, (Datum) 0,
true, true,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.248 2007/09/03 00:39:15 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.249 2007/09/06 17:31:58 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -2265,7 +2265,7 @@ eval_const_expressions_mutator(Node *node,
/* If all the arguments were constant null, the result is just null */ /* If all the arguments were constant null, the result is just null */
if (newargs == NIL) if (newargs == NIL)
return (Node *) makeNullConst(coalesceexpr->coalescetype); return (Node *) makeNullConst(coalesceexpr->coalescetype, -1);
newcoalesce = makeNode(CoalesceExpr); newcoalesce = makeNode(CoalesceExpr);
newcoalesce->coalescetype = coalesceexpr->coalescetype; newcoalesce->coalescetype = coalesceexpr->coalescetype;
@ -2833,7 +2833,7 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, List *args,
* function is not otherwise immutable. * function is not otherwise immutable.
*/ */
if (funcform->proisstrict && has_null_input) if (funcform->proisstrict && has_null_input)
return (Expr *) makeNullConst(result_type); return (Expr *) makeNullConst(result_type, result_typmod);
/* /*
* Otherwise, can simplify only if all inputs are constants. (For a * Otherwise, can simplify only if all inputs are constants. (For a

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.156 2007/08/21 01:11:15 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.157 2007/09/06 17:31:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -816,7 +816,7 @@ coerce_record_to_complex(ParseState *pstate, Node *node,
* can't use atttypid here, but it doesn't really matter what type * can't use atttypid here, but it doesn't really matter what type
* the Const claims to be. * the Const claims to be.
*/ */
newargs = lappend(newargs, makeNullConst(INT4OID)); newargs = lappend(newargs, makeNullConst(INT4OID, -1));
continue; continue;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.127 2007/01/05 22:19:34 momjian Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.128 2007/09/06 17:31:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1448,7 +1448,7 @@ expandTupleDesc(TupleDesc tupdesc, Alias *eref,
* can't use atttypid here, but it doesn't really matter * can't use atttypid here, but it doesn't really matter
* what type the Const claims to be. * what type the Const claims to be.
*/ */
*colvars = lappend(*colvars, makeNullConst(INT4OID)); *colvars = lappend(*colvars, makeNullConst(INT4OID, -1));
} }
} }
continue; continue;

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.154 2007/02/03 14:06:54 petere Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.155 2007/09/06 17:31:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -393,7 +393,7 @@ transformAssignedExpr(ParseState *pstate,
* is not really a source value to work with. Insert a NULL * is not really a source value to work with. Insert a NULL
* constant as the source value. * constant as the source value.
*/ */
colVar = (Node *) makeNullConst(attrtype); colVar = (Node *) makeNullConst(attrtype, attrtypmod);
} }
else else
{ {

View File

@ -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.173 2007/03/19 23:38:29 wieck Exp $ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.174 2007/09/06 17:31:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -193,7 +193,7 @@ AcquireRewriteLocks(Query *parsetree)
* now-dropped type OID, but it doesn't really * now-dropped type OID, but it doesn't really
* matter what type the Const claims to be. * matter what type the Const claims to be.
*/ */
aliasvar = (Var *) makeNullConst(INT4OID); aliasvar = (Var *) makeNullConst(INT4OID, -1);
} }
} }
newaliasvars = lappend(newaliasvars, aliasvar); newaliasvars = lappend(newaliasvars, aliasvar);

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.104 2007/06/11 01:16:25 tgl Exp $ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.105 2007/09/06 17:31:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -896,7 +896,8 @@ resolve_one_var(Var *var, ResolveNew_context *context)
{ {
/* Otherwise replace unmatched var with a null */ /* Otherwise replace unmatched var with a null */
/* need coerce_to_domain in case of NOT NULL domain constraint */ /* need coerce_to_domain in case of NOT NULL domain constraint */
return coerce_to_domain((Node *) makeNullConst(var->vartype), return coerce_to_domain((Node *) makeNullConst(var->vartype,
var->vartypmod),
InvalidOid, -1, InvalidOid, -1,
var->vartype, var->vartype,
COERCE_IMPLICIT_CAST, COERCE_IMPLICIT_CAST,

View File

@ -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.59 2007/06/23 22:12:52 tgl Exp $ * $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.60 2007/09/06 17:31:58 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -45,7 +45,7 @@ extern Const *makeConst(Oid consttype,
bool constisnull, bool constisnull,
bool constbyval); bool constbyval);
extern Const *makeNullConst(Oid consttype); extern Const *makeNullConst(Oid consttype, int32 consttypmod);
extern Node *makeBoolConst(bool value, bool isnull); extern Node *makeBoolConst(bool value, bool isnull);