aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/commands/tablecmds.c4
-rw-r--r--src/backend/executor/execQual.c2
-rw-r--r--src/backend/executor/functions.c2
-rw-r--r--src/backend/nodes/makefuncs.c8
-rw-r--r--src/backend/optimizer/path/indxpath.c43
-rw-r--r--src/backend/optimizer/plan/planagg.c3
-rw-r--r--src/backend/optimizer/prep/preptlist.c3
-rw-r--r--src/backend/optimizer/prep/prepunion.c1
-rw-r--r--src/backend/optimizer/util/clauses.c90
-rw-r--r--src/backend/parser/parse_coerce.c5
-rw-r--r--src/backend/parser/parse_node.c3
-rw-r--r--src/backend/parser/parse_relation.c3
-rw-r--r--src/backend/parser/parse_target.c3
-rw-r--r--src/backend/rewrite/rewriteHandler.c4
-rw-r--r--src/backend/rewrite/rewriteManip.c3
-rw-r--r--src/backend/utils/adt/selfuncs.c40
-rw-r--r--src/backend/utils/cache/lsyscache.c1
17 files changed, 163 insertions, 55 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 596cd864017..d7573b8ef50 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -4337,10 +4337,12 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
{
Oid baseTypeId;
int32 baseTypeMod;
+ Oid baseTypeColl;
baseTypeMod = typmod;
baseTypeId = getBaseTypeAndTypmod(typeOid, &baseTypeMod);
- defval = (Expr *) makeNullConst(baseTypeId, baseTypeMod);
+ baseTypeColl = get_typcollation(baseTypeId);
+ defval = (Expr *) makeNullConst(baseTypeId, baseTypeMod, baseTypeColl);
defval = (Expr *) coerce_to_target_type(NULL,
(Node *) defval,
baseTypeId,
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index e410818900d..c153ca00dbf 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -4653,7 +4653,7 @@ ExecInitExpr(Expr *node, PlanState *parent)
* don't really care what type of NULL it is, so
* always make an int4 NULL.
*/
- e = (Expr *) makeNullConst(INT4OID, -1);
+ e = (Expr *) makeNullConst(INT4OID, -1, InvalidOid);
}
estate = ExecInitExpr(e, parent);
outlist = lappend(outlist, estate);
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index ce3b77b847e..70d126c5213 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -1501,6 +1501,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
/* The type of the null we insert isn't important */
null_expr = (Expr *) makeConst(INT4OID,
-1,
+ InvalidOid,
sizeof(int32),
(Datum) 0,
true, /* isnull */
@@ -1562,6 +1563,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
/* The type of the null we insert isn't important */
null_expr = (Expr *) makeConst(INT4OID,
-1,
+ InvalidOid,
sizeof(int32),
(Datum) 0,
true, /* isnull */
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 41e597cfffb..4d2eccf8179 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -271,6 +271,7 @@ makeFromExpr(List *fromlist, Node *quals)
Const *
makeConst(Oid consttype,
int32 consttypmod,
+ Oid constcollid,
int constlen,
Datum constvalue,
bool constisnull,
@@ -280,7 +281,7 @@ makeConst(Oid consttype,
cnst->consttype = consttype;
cnst->consttypmod = consttypmod;
- cnst->constcollid = get_typcollation(consttype);
+ cnst->constcollid = constcollid;
cnst->constlen = constlen;
cnst->constvalue = constvalue;
cnst->constisnull = constisnull;
@@ -298,7 +299,7 @@ makeConst(Oid consttype,
* storage properties.
*/
Const *
-makeNullConst(Oid consttype, int32 consttypmod)
+makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
{
int16 typLen;
bool typByVal;
@@ -306,6 +307,7 @@ makeNullConst(Oid consttype, int32 consttypmod)
get_typlenbyval(consttype, &typLen, &typByVal);
return makeConst(consttype,
consttypmod,
+ constcollid,
(int) typLen,
(Datum) 0,
true,
@@ -320,7 +322,7 @@ Node *
makeBoolConst(bool value, bool isnull)
{
/* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
- return (Node *) makeConst(BOOLOID, -1, 1,
+ return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
BoolGetDatum(value), isnull, true);
}
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 925155c64d4..ecae57bdbbf 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -19,6 +19,7 @@
#include "access/skey.h"
#include "catalog/pg_am.h"
+#include "catalog/pg_collation.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_type.h"
@@ -3233,7 +3234,9 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop)
expr = make_opclause(opr1oid, BOOLOID, false,
(Expr *) leftop,
- (Expr *) makeConst(datatype, -1, -1, opr1right,
+ (Expr *) makeConst(datatype, -1,
+ InvalidOid, /* not collatable */
+ -1, opr1right,
false, false),
InvalidOid, InvalidOid);
result = list_make1(make_simple_restrictinfo(expr));
@@ -3249,7 +3252,9 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop)
expr = make_opclause(opr2oid, BOOLOID, false,
(Expr *) leftop,
- (Expr *) makeConst(datatype, -1, -1, opr2right,
+ (Expr *) makeConst(datatype, -1,
+ InvalidOid, /* not collatable */
+ -1, opr2right,
false, false),
InvalidOid, InvalidOid);
result = lappend(result, make_simple_restrictinfo(expr));
@@ -3288,8 +3293,38 @@ static Const *
string_to_const(const char *str, Oid datatype)
{
Datum conval = string_to_datum(str, datatype);
+ Oid collation;
+ int constlen;
- return makeConst(datatype, -1,
- ((datatype == NAMEOID) ? NAMEDATALEN : -1),
+ /*
+ * We only need to support a few datatypes here, so hard-wire properties
+ * instead of incurring the expense of catalog lookups.
+ */
+ switch (datatype)
+ {
+ case TEXTOID:
+ case VARCHAROID:
+ case BPCHAROID:
+ collation = DEFAULT_COLLATION_OID;
+ constlen = -1;
+ break;
+
+ case NAMEOID:
+ collation = InvalidOid;
+ constlen = NAMEDATALEN;
+ break;
+
+ case BYTEAOID:
+ collation = InvalidOid;
+ constlen = -1;
+ break;
+
+ default:
+ elog(ERROR, "unexpected datatype in string_to_const: %u",
+ datatype);
+ return NULL;
+ }
+
+ return makeConst(datatype, -1, collation, constlen,
conval, false, false);
}
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index 39203703e61..f2ddf2a8442 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -429,7 +429,8 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo,
/* set up expressions for LIMIT 1 */
parse->limitOffset = NULL;
- parse->limitCount = (Node *) makeConst(INT8OID, -1, sizeof(int64),
+ parse->limitCount = (Node *) makeConst(INT8OID, -1, InvalidOid,
+ sizeof(int64),
Int64GetDatum(1), false,
FLOAT8PASSBYVAL);
diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index 63447aa536e..4ba8921528f 100644
--- a/src/backend/optimizer/prep/preptlist.c
+++ b/src/backend/optimizer/prep/preptlist.c
@@ -269,6 +269,7 @@ expand_targetlist(List *tlist, int command_type,
{
new_expr = (Node *) makeConst(atttype,
-1,
+ attcollation,
att_tup->attlen,
(Datum) 0,
true, /* isnull */
@@ -286,6 +287,7 @@ expand_targetlist(List *tlist, int command_type,
/* Insert NULL for dropped column */
new_expr = (Node *) makeConst(INT4OID,
-1,
+ InvalidOid,
sizeof(int32),
(Datum) 0,
true, /* isnull */
@@ -307,6 +309,7 @@ expand_targetlist(List *tlist, int command_type,
/* Insert NULL for dropped column */
new_expr = (Node *) makeConst(INT4OID,
-1,
+ InvalidOid,
sizeof(int32),
(Datum) 0,
true, /* isnull */
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 606e5fe60a5..e15a8620426 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -910,6 +910,7 @@ generate_setop_tlist(List *colTypes, int flag,
/* flag value is the given constant */
expr = (Node *) makeConst(INT4OID,
-1,
+ InvalidOid,
sizeof(int4),
Int32GetDatum(flag),
false,
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 0fddbae60a3..1a63146e6f1 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -101,7 +101,7 @@ static List *simplify_and_arguments(List *args,
static Node *simplify_boolean_equality(Oid opno, List *args);
static Expr *simplify_function(Oid funcid,
Oid result_type, int32 result_typmod,
- Oid input_collid, List **args,
+ Oid result_collid, Oid input_collid, List **args,
bool has_named_args,
bool allow_inline,
eval_const_expressions_context *context);
@@ -114,19 +114,21 @@ static List *add_function_defaults(List *args, Oid result_type,
static List *fetch_function_defaults(HeapTuple func_tuple);
static void recheck_cast_function_args(List *args, Oid result_type,
HeapTuple func_tuple);
-static Expr *evaluate_function(Oid funcid,
- Oid result_type, int32 result_typmod,
- Oid input_collid, List *args, HeapTuple func_tuple,
+static Expr *evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
+ Oid result_collid, Oid input_collid, List *args,
+ HeapTuple func_tuple,
eval_const_expressions_context *context);
-static Expr *inline_function(Oid funcid, Oid result_type, Oid input_collid,
- List *args, HeapTuple func_tuple,
+static Expr *inline_function(Oid funcid, Oid result_type, Oid result_collid,
+ Oid input_collid, List *args,
+ HeapTuple func_tuple,
eval_const_expressions_context *context);
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);
static void sql_inline_error_callback(void *arg);
-static Expr *evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod);
+static Expr *evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod,
+ Oid result_collation);
static Query *substitute_actual_srf_parameters(Query *expr,
int nargs, List *args);
static Node *substitute_actual_srf_parameters_mutator(Node *node,
@@ -2141,7 +2143,6 @@ eval_const_expressions_mutator(Node *node,
int16 typLen;
bool typByVal;
Datum pval;
- Const *cnst;
Assert(prm->ptype == param->paramtype);
get_typlenbyval(param->paramtype, &typLen, &typByVal);
@@ -2149,14 +2150,13 @@ eval_const_expressions_mutator(Node *node,
pval = prm->value;
else
pval = datumCopy(prm->value, typByVal, typLen);
- cnst = makeConst(param->paramtype,
- param->paramtypmod,
- (int) typLen,
- pval,
- prm->isnull,
- typByVal);
- cnst->constcollid = param->paramcollid;
- return (Node *) cnst;
+ return (Node *) makeConst(param->paramtype,
+ param->paramtypmod,
+ param->paramcollid,
+ (int) typLen,
+ pval,
+ prm->isnull,
+ typByVal);
}
}
}
@@ -2196,6 +2196,7 @@ eval_const_expressions_mutator(Node *node,
*/
simple = simplify_function(expr->funcid,
expr->funcresulttype, exprTypmod(node),
+ expr->funccollid,
expr->inputcollid,
&args,
has_named_args, true, context);
@@ -2247,6 +2248,7 @@ eval_const_expressions_mutator(Node *node,
*/
simple = simplify_function(expr->opfuncid,
expr->opresulttype, -1,
+ expr->opcollid,
expr->inputcollid,
&args,
false, true, context);
@@ -2343,6 +2345,7 @@ eval_const_expressions_mutator(Node *node,
*/
simple = simplify_function(expr->opfuncid,
expr->opresulttype, -1,
+ expr->opcollid,
expr->inputcollid,
&args,
false, false, context);
@@ -2532,6 +2535,7 @@ eval_const_expressions_mutator(Node *node,
simple = simplify_function(outfunc,
CSTRINGOID, -1,
InvalidOid,
+ InvalidOid,
&args,
false, true, context);
if (simple) /* successfully simplified output fn */
@@ -2541,15 +2545,16 @@ eval_const_expressions_mutator(Node *node,
* all three, trusting that nothing downstream will complain.
*/
args = list_make3(simple,
- makeConst(OIDOID, -1, sizeof(Oid),
+ makeConst(OIDOID, -1, InvalidOid, sizeof(Oid),
ObjectIdGetDatum(intypioparam),
false, true),
- makeConst(INT4OID, -1, sizeof(int32),
+ makeConst(INT4OID, -1, InvalidOid, sizeof(int32),
Int32GetDatum(-1),
false, true));
simple = simplify_function(infunc,
expr->resulttype, -1,
+ expr->resultcollid,
InvalidOid,
&args,
false, true, context);
@@ -2602,7 +2607,8 @@ eval_const_expressions_mutator(Node *node,
func_volatile(newexpr->elemfuncid) == PROVOLATILE_IMMUTABLE))
return (Node *) evaluate_expr((Expr *) newexpr,
newexpr->resulttype,
- newexpr->resulttypmod);
+ newexpr->resulttypmod,
+ newexpr->resultcollid);
/* Else we must return the partially-simplified node */
return (Node *) newexpr;
@@ -2826,7 +2832,8 @@ eval_const_expressions_mutator(Node *node,
if (all_const)
return (Node *) evaluate_expr((Expr *) newarray,
newarray->array_typeid,
- exprTypmod(node));
+ exprTypmod(node),
+ newarray->array_collid);
return (Node *) newarray;
}
@@ -2866,7 +2873,9 @@ eval_const_expressions_mutator(Node *node,
/* If all the arguments were constant null, the result is just null */
if (newargs == NIL)
- return (Node *) makeNullConst(coalesceexpr->coalescetype, -1);
+ return (Node *) makeNullConst(coalesceexpr->coalescetype,
+ -1,
+ coalesceexpr->coalescecollid);
newcoalesce = makeNode(CoalesceExpr);
newcoalesce->coalescetype = coalesceexpr->coalescetype;
@@ -3380,7 +3389,8 @@ simplify_boolean_equality(Oid opno, 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 typmod, input collation to use for the function,
+ * polymorphic functions), result typmod, result collation,
+ * the input collation to use for the function,
* the pre-simplified argument list, and some flags;
* also the context data for eval_const_expressions.
*
@@ -3395,8 +3405,7 @@ simplify_boolean_equality(Oid opno, List *args)
*/
static Expr *
simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
- Oid input_collid,
- List **args,
+ Oid result_collid, Oid input_collid, List **args,
bool has_named_args,
bool allow_inline,
eval_const_expressions_context *context)
@@ -3427,11 +3436,12 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
*args = add_function_defaults(*args, result_type, func_tuple, context);
newexpr = evaluate_function(funcid, result_type, result_typmod,
- input_collid, *args,
+ result_collid, input_collid, *args,
func_tuple, context);
if (!newexpr && allow_inline)
- newexpr = inline_function(funcid, result_type, input_collid, *args,
+ newexpr = inline_function(funcid, result_type, result_collid,
+ input_collid, *args,
func_tuple, context);
ReleaseSysCache(func_tuple);
@@ -3679,7 +3689,8 @@ recheck_cast_function_args(List *args, Oid result_type, HeapTuple func_tuple)
*/
static Expr *
evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
- Oid input_collid, List *args, HeapTuple func_tuple,
+ Oid result_collid, Oid input_collid, List *args,
+ HeapTuple func_tuple,
eval_const_expressions_context *context)
{
Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
@@ -3726,7 +3737,8 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
* function is not otherwise immutable.
*/
if (funcform->proisstrict && has_null_input)
- return (Expr *) makeNullConst(result_type, result_typmod);
+ return (Expr *) makeNullConst(result_type, result_typmod,
+ result_collid);
/*
* Otherwise, can simplify only if all inputs are constants. (For a
@@ -3760,12 +3772,13 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
newexpr->funcresulttype = result_type;
newexpr->funcretset = false;
newexpr->funcformat = COERCE_DONTCARE; /* doesn't matter */
- newexpr->funccollid = InvalidOid; /* doesn't matter */
+ newexpr->funccollid = result_collid; /* doesn't matter */
newexpr->inputcollid = input_collid;
newexpr->args = args;
newexpr->location = -1;
- return evaluate_expr((Expr *) newexpr, result_type, result_typmod);
+ return evaluate_expr((Expr *) newexpr, result_type, result_typmod,
+ result_collid);
}
/*
@@ -3798,7 +3811,8 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
* simplify the function.
*/
static Expr *
-inline_function(Oid funcid, Oid result_type, Oid input_collid, List *args,
+inline_function(Oid funcid, Oid result_type, Oid result_collid,
+ Oid input_collid, List *args,
HeapTuple func_tuple,
eval_const_expressions_context *context)
{
@@ -3888,7 +3902,7 @@ inline_function(Oid funcid, Oid result_type, Oid input_collid, List *args,
fexpr->funcresulttype = result_type;
fexpr->funcretset = false;
fexpr->funcformat = COERCE_DONTCARE; /* doesn't matter */
- fexpr->funccollid = InvalidOid; /* doesn't matter */
+ fexpr->funccollid = result_collid; /* doesn't matter */
fexpr->inputcollid = input_collid;
fexpr->args = args;
fexpr->location = -1;
@@ -4051,16 +4065,16 @@ inline_function(Oid funcid, Oid result_type, Oid input_collid, List *args,
* it's possible that the function result is used directly as a sort key
* or in other places where we expect exprCollation() to tell the truth.
*/
- if (OidIsValid(input_collid))
+ if (OidIsValid(result_collid))
{
Oid exprcoll = exprCollation(newexpr);
- if (OidIsValid(exprcoll) && exprcoll != input_collid)
+ if (OidIsValid(exprcoll) && exprcoll != result_collid)
{
CollateExpr *newnode = makeNode(CollateExpr);
newnode->arg = (Expr *) newexpr;
- newnode->collOid = input_collid;
+ newnode->collOid = result_collid;
newnode->location = -1;
newexpr = (Node *) newnode;
@@ -4165,7 +4179,8 @@ 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, int32 result_typmod)
+evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod,
+ Oid result_collation)
{
EState *estate;
ExprState *exprstate;
@@ -4231,7 +4246,8 @@ evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod)
/*
* Make the constant result node.
*/
- return (Expr *) makeConst(result_type, result_typmod, resultTypLen,
+ return (Expr *) makeConst(result_type, result_typmod, result_collation,
+ resultTypLen,
const_val, const_is_null,
resultTypByVal);
}
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 9b59b032976..cc03f9f48e6 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -753,6 +753,7 @@ build_coercion_expression(Node *node,
/* Pass target typmod as an int4 constant */
cons = makeConst(INT4OID,
-1,
+ InvalidOid,
sizeof(int32),
Int32GetDatum(targetTypMod),
false,
@@ -766,6 +767,7 @@ build_coercion_expression(Node *node,
/* Pass it a boolean isExplicit parameter, too */
cons = makeConst(BOOLOID,
-1,
+ InvalidOid,
sizeof(bool),
BoolGetDatum(isExplicit),
false,
@@ -890,7 +892,8 @@ coerce_record_to_complex(ParseState *pstate, Node *node,
* can't use atttypid here, but it doesn't really matter what type
* the Const claims to be.
*/
- newargs = lappend(newargs, makeNullConst(INT4OID, -1));
+ newargs = lappend(newargs,
+ makeNullConst(INT4OID, -1, InvalidOid));
continue;
}
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index 2c76c557ecc..07257accc82 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -347,6 +347,7 @@ transformArraySubscripts(ParseState *pstate,
/* Make a constant 1 */
subexpr = (Node *) makeConst(INT4OID,
-1,
+ InvalidOid,
sizeof(int32),
Int32GetDatum(1),
false,
@@ -526,6 +527,7 @@ make_const(ParseState *pstate, Value *value, int location)
/* return a null const */
con = makeConst(UNKNOWNOID,
-1,
+ InvalidOid,
-2,
(Datum) 0,
true,
@@ -540,6 +542,7 @@ make_const(ParseState *pstate, Value *value, int location)
con = makeConst(typeid,
-1, /* typmod -1 is OK for all cases */
+ InvalidOid, /* all cases are uncollatable types */
typelen,
val,
false,
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 488b1425a35..7bfafdb5cfb 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -1870,7 +1870,8 @@ expandTupleDesc(TupleDesc tupdesc, Alias *eref,
* can't use atttypid here, but it doesn't really matter
* what type the Const claims to be.
*/
- *colvars = lappend(*colvars, makeNullConst(INT4OID, -1));
+ *colvars = lappend(*colvars,
+ makeNullConst(INT4OID, -1, InvalidOid));
}
}
continue;
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 550783547e8..8e92b99b5b2 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -434,7 +434,8 @@ transformAssignedExpr(ParseState *pstate,
* is not really a source value to work with. Insert a NULL
* constant as the source value.
*/
- colVar = (Node *) makeNullConst(attrtype, attrtypmod);
+ colVar = (Node *) makeNullConst(attrtype, attrtypmod,
+ attrcollation);
}
else
{
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 87d39174a44..a695b012399 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -208,7 +208,7 @@ AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown)
* now-dropped type OID, but it doesn't really
* matter what type the Const claims to be.
*/
- aliasvar = (Var *) makeNullConst(INT4OID, -1);
+ aliasvar = (Var *) makeNullConst(INT4OID, -1, InvalidOid);
}
}
newaliasvars = lappend(newaliasvars, aliasvar);
@@ -719,6 +719,7 @@ rewriteTargetListIU(Query *parsetree, Relation target_relation,
{
new_expr = (Node *) makeConst(att_tup->atttypid,
-1,
+ att_tup->attcollation,
att_tup->attlen,
(Datum) 0,
true, /* isnull */
@@ -1082,6 +1083,7 @@ rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation, List *attrnos)
{
new_expr = (Node *) makeConst(att_tup->atttypid,
-1,
+ att_tup->attcollation,
att_tup->attlen,
(Datum) 0,
true, /* isnull */
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index 49a6df0e807..d3985b2093e 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -1281,7 +1281,8 @@ ResolveNew_callback(Var *var,
/* Otherwise replace unmatched var with a null */
/* need coerce_to_domain in case of NOT NULL domain constraint */
return coerce_to_domain((Node *) makeNullConst(var->vartype,
- var->vartypmod),
+ var->vartypmod,
+ var->varcollid),
InvalidOid, -1,
var->vartype,
COERCE_IMPLICIT_CAST,
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 33f300bfea2..c757fcb424f 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -1686,6 +1686,7 @@ scalararraysel(PlannerInfo *root,
Node *leftop;
Node *rightop;
Oid nominal_element_type;
+ Oid nominal_element_collation;
RegProcedure oprsel;
FmgrInfo oprselproc;
Selectivity s1;
@@ -1712,6 +1713,8 @@ scalararraysel(PlannerInfo *root,
nominal_element_type = get_base_element_type(exprType(rightop));
if (!OidIsValid(nominal_element_type))
return (Selectivity) 0.5; /* probably shouldn't happen */
+ /* get nominal collation, too, for generating constants */
+ nominal_element_collation = exprCollation(rightop);
/* look through any binary-compatible relabeling of rightop */
rightop = strip_array_coercion(rightop);
@@ -1759,6 +1762,7 @@ scalararraysel(PlannerInfo *root,
args = list_make2(leftop,
makeConst(nominal_element_type,
-1,
+ nominal_element_collation,
elmlen,
elem_values[i],
elem_nulls[i],
@@ -5616,9 +5620,39 @@ static Const *
string_to_const(const char *str, Oid datatype)
{
Datum conval = string_to_datum(str, datatype);
+ Oid collation;
+ int constlen;
- return makeConst(datatype, -1,
- ((datatype == NAMEOID) ? NAMEDATALEN : -1),
+ /*
+ * We only need to support a few datatypes here, so hard-wire properties
+ * instead of incurring the expense of catalog lookups.
+ */
+ switch (datatype)
+ {
+ case TEXTOID:
+ case VARCHAROID:
+ case BPCHAROID:
+ collation = DEFAULT_COLLATION_OID;
+ constlen = -1;
+ break;
+
+ case NAMEOID:
+ collation = InvalidOid;
+ constlen = NAMEDATALEN;
+ break;
+
+ case BYTEAOID:
+ collation = InvalidOid;
+ constlen = -1;
+ break;
+
+ default:
+ elog(ERROR, "unexpected datatype in string_to_const: %u",
+ datatype);
+ return NULL;
+ }
+
+ return makeConst(datatype, -1, collation, constlen,
conval, false, false);
}
@@ -5635,7 +5669,7 @@ string_to_bytea_const(const char *str, size_t str_len)
SET_VARSIZE(bstr, VARHDRSZ + str_len);
conval = PointerGetDatum(bstr);
- return makeConst(BYTEAOID, -1, -1, conval, false, false);
+ return makeConst(BYTEAOID, -1, InvalidOid, -1, conval, false, false);
}
/*-------------------------------------------------------------------------
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 6af23429ad8..6bcaf30ffe7 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2084,6 +2084,7 @@ get_typdefault(Oid typid)
/* Build a Const node containing the value */
expr = (Node *) makeConst(typid,
-1,
+ type->typcollation,
type->typlen,
datum,
false,