Commit bfa4440c authored by Tom Lane's avatar Tom Lane

Pass collation to makeConst() instead of looking it up internally.

In nearly all cases, the caller already knows the correct collation, and
in a number of places, the value the caller has handy is more correct than
the default for the type would be.  (In particular, this patch makes it
significantly less likely that eval_const_expressions will result in
changing the exposed collation of an expression.)  So an internal lookup
is both expensive and wrong.
parent c8e99350
...@@ -4337,10 +4337,12 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel, ...@@ -4337,10 +4337,12 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
{ {
Oid baseTypeId; Oid baseTypeId;
int32 baseTypeMod; int32 baseTypeMod;
Oid baseTypeColl;
baseTypeMod = typmod; baseTypeMod = typmod;
baseTypeId = getBaseTypeAndTypmod(typeOid, &baseTypeMod); 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, defval = (Expr *) coerce_to_target_type(NULL,
(Node *) defval, (Node *) defval,
baseTypeId, baseTypeId,
......
...@@ -4653,7 +4653,7 @@ ExecInitExpr(Expr *node, PlanState *parent) ...@@ -4653,7 +4653,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, -1); e = (Expr *) makeNullConst(INT4OID, -1, InvalidOid);
} }
estate = ExecInitExpr(e, parent); estate = ExecInitExpr(e, parent);
outlist = lappend(outlist, estate); outlist = lappend(outlist, estate);
......
...@@ -1501,6 +1501,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, ...@@ -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 */ /* The type of the null we insert isn't important */
null_expr = (Expr *) makeConst(INT4OID, null_expr = (Expr *) makeConst(INT4OID,
-1, -1,
InvalidOid,
sizeof(int32), sizeof(int32),
(Datum) 0, (Datum) 0,
true, /* isnull */ true, /* isnull */
...@@ -1562,6 +1563,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, ...@@ -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 */ /* The type of the null we insert isn't important */
null_expr = (Expr *) makeConst(INT4OID, null_expr = (Expr *) makeConst(INT4OID,
-1, -1,
InvalidOid,
sizeof(int32), sizeof(int32),
(Datum) 0, (Datum) 0,
true, /* isnull */ true, /* isnull */
......
...@@ -271,6 +271,7 @@ makeFromExpr(List *fromlist, Node *quals) ...@@ -271,6 +271,7 @@ makeFromExpr(List *fromlist, Node *quals)
Const * Const *
makeConst(Oid consttype, makeConst(Oid consttype,
int32 consttypmod, int32 consttypmod,
Oid constcollid,
int constlen, int constlen,
Datum constvalue, Datum constvalue,
bool constisnull, bool constisnull,
...@@ -280,7 +281,7 @@ makeConst(Oid consttype, ...@@ -280,7 +281,7 @@ makeConst(Oid consttype,
cnst->consttype = consttype; cnst->consttype = consttype;
cnst->consttypmod = consttypmod; cnst->consttypmod = consttypmod;
cnst->constcollid = get_typcollation(consttype); cnst->constcollid = constcollid;
cnst->constlen = constlen; cnst->constlen = constlen;
cnst->constvalue = constvalue; cnst->constvalue = constvalue;
cnst->constisnull = constisnull; cnst->constisnull = constisnull;
...@@ -298,7 +299,7 @@ makeConst(Oid consttype, ...@@ -298,7 +299,7 @@ makeConst(Oid consttype,
* storage properties. * storage properties.
*/ */
Const * Const *
makeNullConst(Oid consttype, int32 consttypmod) makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
{ {
int16 typLen; int16 typLen;
bool typByVal; bool typByVal;
...@@ -306,6 +307,7 @@ makeNullConst(Oid consttype, int32 consttypmod) ...@@ -306,6 +307,7 @@ makeNullConst(Oid consttype, int32 consttypmod)
get_typlenbyval(consttype, &typLen, &typByVal); get_typlenbyval(consttype, &typLen, &typByVal);
return makeConst(consttype, return makeConst(consttype,
consttypmod, consttypmod,
constcollid,
(int) typLen, (int) typLen,
(Datum) 0, (Datum) 0,
true, true,
...@@ -320,7 +322,7 @@ Node * ...@@ -320,7 +322,7 @@ 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, 1, return (Node *) makeConst(BOOLOID, -1, InvalidOid, 1,
BoolGetDatum(value), isnull, true); BoolGetDatum(value), isnull, true);
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "access/skey.h" #include "access/skey.h"
#include "catalog/pg_am.h" #include "catalog/pg_am.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h" #include "catalog/pg_opfamily.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
...@@ -3233,7 +3234,9 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop) ...@@ -3233,7 +3234,9 @@ 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, -1, opr1right, (Expr *) makeConst(datatype, -1,
InvalidOid, /* not collatable */
-1, opr1right,
false, false), false, false),
InvalidOid, InvalidOid); InvalidOid, InvalidOid);
result = list_make1(make_simple_restrictinfo(expr)); result = list_make1(make_simple_restrictinfo(expr));
...@@ -3249,7 +3252,9 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop) ...@@ -3249,7 +3252,9 @@ 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, -1, opr2right, (Expr *) makeConst(datatype, -1,
InvalidOid, /* not collatable */
-1, opr2right,
false, false), false, false),
InvalidOid, InvalidOid); InvalidOid, InvalidOid);
result = lappend(result, make_simple_restrictinfo(expr)); result = lappend(result, make_simple_restrictinfo(expr));
...@@ -3288,8 +3293,38 @@ static Const * ...@@ -3288,8 +3293,38 @@ static Const *
string_to_const(const char *str, Oid datatype) string_to_const(const char *str, Oid datatype)
{ {
Datum conval = string_to_datum(str, 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); conval, false, false);
} }
...@@ -429,7 +429,8 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo, ...@@ -429,7 +429,8 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo,
/* set up expressions for LIMIT 1 */ /* set up expressions for LIMIT 1 */
parse->limitOffset = NULL; parse->limitOffset = NULL;
parse->limitCount = (Node *) makeConst(INT8OID, -1, sizeof(int64), parse->limitCount = (Node *) makeConst(INT8OID, -1, InvalidOid,
sizeof(int64),
Int64GetDatum(1), false, Int64GetDatum(1), false,
FLOAT8PASSBYVAL); FLOAT8PASSBYVAL);
......
...@@ -269,6 +269,7 @@ expand_targetlist(List *tlist, int command_type, ...@@ -269,6 +269,7 @@ expand_targetlist(List *tlist, int command_type,
{ {
new_expr = (Node *) makeConst(atttype, new_expr = (Node *) makeConst(atttype,
-1, -1,
attcollation,
att_tup->attlen, att_tup->attlen,
(Datum) 0, (Datum) 0,
true, /* isnull */ true, /* isnull */
...@@ -286,6 +287,7 @@ expand_targetlist(List *tlist, int command_type, ...@@ -286,6 +287,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, -1,
InvalidOid,
sizeof(int32), sizeof(int32),
(Datum) 0, (Datum) 0,
true, /* isnull */ true, /* isnull */
...@@ -307,6 +309,7 @@ expand_targetlist(List *tlist, int command_type, ...@@ -307,6 +309,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, -1,
InvalidOid,
sizeof(int32), sizeof(int32),
(Datum) 0, (Datum) 0,
true, /* isnull */ true, /* isnull */
......
...@@ -910,6 +910,7 @@ generate_setop_tlist(List *colTypes, int flag, ...@@ -910,6 +910,7 @@ generate_setop_tlist(List *colTypes, int flag,
/* flag value is the given constant */ /* flag value is the given constant */
expr = (Node *) makeConst(INT4OID, expr = (Node *) makeConst(INT4OID,
-1, -1,
InvalidOid,
sizeof(int4), sizeof(int4),
Int32GetDatum(flag), Int32GetDatum(flag),
false, false,
......
...@@ -101,7 +101,7 @@ static List *simplify_and_arguments(List *args, ...@@ -101,7 +101,7 @@ static List *simplify_and_arguments(List *args,
static Node *simplify_boolean_equality(Oid opno, List *args); static Node *simplify_boolean_equality(Oid opno, List *args);
static Expr *simplify_function(Oid funcid, static Expr *simplify_function(Oid funcid,
Oid result_type, int32 result_typmod, Oid result_type, int32 result_typmod,
Oid input_collid, List **args, Oid result_collid, Oid input_collid, List **args,
bool has_named_args, bool has_named_args,
bool allow_inline, bool allow_inline,
eval_const_expressions_context *context); eval_const_expressions_context *context);
...@@ -114,19 +114,21 @@ static List *add_function_defaults(List *args, Oid result_type, ...@@ -114,19 +114,21 @@ static List *add_function_defaults(List *args, Oid result_type,
static List *fetch_function_defaults(HeapTuple func_tuple); static List *fetch_function_defaults(HeapTuple func_tuple);
static void recheck_cast_function_args(List *args, Oid result_type, static void recheck_cast_function_args(List *args, Oid result_type,
HeapTuple func_tuple); HeapTuple func_tuple);
static Expr *evaluate_function(Oid funcid, static Expr *evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
Oid result_type, int32 result_typmod, Oid result_collid, Oid input_collid, List *args,
Oid input_collid, 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, Oid input_collid, static Expr *inline_function(Oid funcid, Oid result_type, Oid result_collid,
List *args, HeapTuple func_tuple, Oid input_collid, List *args,
HeapTuple func_tuple,
eval_const_expressions_context *context); eval_const_expressions_context *context);
static Node *substitute_actual_parameters(Node *expr, int nargs, List *args, static Node *substitute_actual_parameters(Node *expr, int nargs, List *args,
int *usecounts); int *usecounts);
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, 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, static Query *substitute_actual_srf_parameters(Query *expr,
int nargs, List *args); int nargs, List *args);
static Node *substitute_actual_srf_parameters_mutator(Node *node, static Node *substitute_actual_srf_parameters_mutator(Node *node,
...@@ -2141,7 +2143,6 @@ eval_const_expressions_mutator(Node *node, ...@@ -2141,7 +2143,6 @@ eval_const_expressions_mutator(Node *node,
int16 typLen; int16 typLen;
bool typByVal; bool typByVal;
Datum pval; Datum pval;
Const *cnst;
Assert(prm->ptype == param->paramtype); Assert(prm->ptype == param->paramtype);
get_typlenbyval(param->paramtype, &typLen, &typByVal); get_typlenbyval(param->paramtype, &typLen, &typByVal);
...@@ -2149,14 +2150,13 @@ eval_const_expressions_mutator(Node *node, ...@@ -2149,14 +2150,13 @@ eval_const_expressions_mutator(Node *node,
pval = prm->value; pval = prm->value;
else else
pval = datumCopy(prm->value, typByVal, typLen); pval = datumCopy(prm->value, typByVal, typLen);
cnst = makeConst(param->paramtype, return (Node *) makeConst(param->paramtype,
param->paramtypmod, param->paramtypmod,
(int) typLen, param->paramcollid,
pval, (int) typLen,
prm->isnull, pval,
typByVal); prm->isnull,
cnst->constcollid = param->paramcollid; typByVal);
return (Node *) cnst;
} }
} }
} }
...@@ -2196,6 +2196,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2196,6 +2196,7 @@ eval_const_expressions_mutator(Node *node,
*/ */
simple = simplify_function(expr->funcid, simple = simplify_function(expr->funcid,
expr->funcresulttype, exprTypmod(node), expr->funcresulttype, exprTypmod(node),
expr->funccollid,
expr->inputcollid, expr->inputcollid,
&args, &args,
has_named_args, true, context); has_named_args, true, context);
...@@ -2247,6 +2248,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2247,6 +2248,7 @@ eval_const_expressions_mutator(Node *node,
*/ */
simple = simplify_function(expr->opfuncid, simple = simplify_function(expr->opfuncid,
expr->opresulttype, -1, expr->opresulttype, -1,
expr->opcollid,
expr->inputcollid, expr->inputcollid,
&args, &args,
false, true, context); false, true, context);
...@@ -2343,6 +2345,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2343,6 +2345,7 @@ eval_const_expressions_mutator(Node *node,
*/ */
simple = simplify_function(expr->opfuncid, simple = simplify_function(expr->opfuncid,
expr->opresulttype, -1, expr->opresulttype, -1,
expr->opcollid,
expr->inputcollid, expr->inputcollid,
&args, &args,
false, false, context); false, false, context);
...@@ -2532,6 +2535,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2532,6 +2535,7 @@ eval_const_expressions_mutator(Node *node,
simple = simplify_function(outfunc, simple = simplify_function(outfunc,
CSTRINGOID, -1, CSTRINGOID, -1,
InvalidOid, InvalidOid,
InvalidOid,
&args, &args,
false, true, context); false, true, context);
if (simple) /* successfully simplified output fn */ if (simple) /* successfully simplified output fn */
...@@ -2541,15 +2545,16 @@ eval_const_expressions_mutator(Node *node, ...@@ -2541,15 +2545,16 @@ eval_const_expressions_mutator(Node *node,
* all three, trusting that nothing downstream will complain. * all three, trusting that nothing downstream will complain.
*/ */
args = list_make3(simple, args = list_make3(simple,
makeConst(OIDOID, -1, sizeof(Oid), makeConst(OIDOID, -1, InvalidOid, sizeof(Oid),
ObjectIdGetDatum(intypioparam), ObjectIdGetDatum(intypioparam),
false, true), false, true),
makeConst(INT4OID, -1, sizeof(int32), makeConst(INT4OID, -1, InvalidOid, sizeof(int32),
Int32GetDatum(-1), Int32GetDatum(-1),
false, true)); false, true));
simple = simplify_function(infunc, simple = simplify_function(infunc,
expr->resulttype, -1, expr->resulttype, -1,
expr->resultcollid,
InvalidOid, InvalidOid,
&args, &args,
false, true, context); false, true, context);
...@@ -2602,7 +2607,8 @@ eval_const_expressions_mutator(Node *node, ...@@ -2602,7 +2607,8 @@ eval_const_expressions_mutator(Node *node,
func_volatile(newexpr->elemfuncid) == PROVOLATILE_IMMUTABLE)) func_volatile(newexpr->elemfuncid) == PROVOLATILE_IMMUTABLE))
return (Node *) evaluate_expr((Expr *) newexpr, return (Node *) evaluate_expr((Expr *) newexpr,
newexpr->resulttype, newexpr->resulttype,
newexpr->resulttypmod); newexpr->resulttypmod,
newexpr->resultcollid);
/* Else we must return the partially-simplified node */ /* Else we must return the partially-simplified node */
return (Node *) newexpr; return (Node *) newexpr;
...@@ -2826,7 +2832,8 @@ eval_const_expressions_mutator(Node *node, ...@@ -2826,7 +2832,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)); exprTypmod(node),
newarray->array_collid);
return (Node *) newarray; return (Node *) newarray;
} }
...@@ -2866,7 +2873,9 @@ eval_const_expressions_mutator(Node *node, ...@@ -2866,7 +2873,9 @@ 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, -1); return (Node *) makeNullConst(coalesceexpr->coalescetype,
-1,
coalesceexpr->coalescecollid);
newcoalesce = makeNode(CoalesceExpr); newcoalesce = makeNode(CoalesceExpr);
newcoalesce->coalescetype = coalesceexpr->coalescetype; newcoalesce->coalescetype = coalesceexpr->coalescetype;
...@@ -3380,7 +3389,8 @@ simplify_boolean_equality(Oid opno, List *args) ...@@ -3380,7 +3389,8 @@ simplify_boolean_equality(Oid opno, 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 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; * the pre-simplified argument list, and some flags;
* also the context data for eval_const_expressions. * also the context data for eval_const_expressions.
* *
...@@ -3395,8 +3405,7 @@ simplify_boolean_equality(Oid opno, List *args) ...@@ -3395,8 +3405,7 @@ simplify_boolean_equality(Oid opno, List *args)
*/ */
static Expr * static Expr *
simplify_function(Oid funcid, Oid result_type, int32 result_typmod, simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
Oid input_collid, Oid result_collid, Oid input_collid, List **args,
List **args,
bool has_named_args, bool has_named_args,
bool allow_inline, bool allow_inline,
eval_const_expressions_context *context) eval_const_expressions_context *context)
...@@ -3427,11 +3436,12 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod, ...@@ -3427,11 +3436,12 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
*args = add_function_defaults(*args, result_type, func_tuple, context); *args = add_function_defaults(*args, result_type, func_tuple, context);
newexpr = evaluate_function(funcid, result_type, result_typmod, newexpr = evaluate_function(funcid, result_type, result_typmod,
input_collid, *args, result_collid, input_collid, *args,
func_tuple, context); func_tuple, context);
if (!newexpr && allow_inline) 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); func_tuple, context);
ReleaseSysCache(func_tuple); ReleaseSysCache(func_tuple);
...@@ -3679,7 +3689,8 @@ recheck_cast_function_args(List *args, Oid result_type, HeapTuple func_tuple) ...@@ -3679,7 +3689,8 @@ recheck_cast_function_args(List *args, Oid result_type, HeapTuple func_tuple)
*/ */
static Expr * static Expr *
evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, 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) eval_const_expressions_context *context)
{ {
Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple); Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
...@@ -3726,7 +3737,8 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, ...@@ -3726,7 +3737,8 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
* 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, result_typmod); return (Expr *) makeNullConst(result_type, result_typmod,
result_collid);
/* /*
* Otherwise, can simplify only if all inputs are constants. (For a * 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, ...@@ -3760,12 +3772,13 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
newexpr->funcresulttype = result_type; newexpr->funcresulttype = result_type;
newexpr->funcretset = false; newexpr->funcretset = false;
newexpr->funcformat = COERCE_DONTCARE; /* doesn't matter */ 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->inputcollid = input_collid;
newexpr->args = args; newexpr->args = args;
newexpr->location = -1; 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, ...@@ -3798,7 +3811,8 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
* simplify the function. * simplify the function.
*/ */
static Expr * 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, HeapTuple func_tuple,
eval_const_expressions_context *context) eval_const_expressions_context *context)
{ {
...@@ -3888,7 +3902,7 @@ inline_function(Oid funcid, Oid result_type, Oid input_collid, List *args, ...@@ -3888,7 +3902,7 @@ inline_function(Oid funcid, Oid result_type, Oid input_collid, List *args,
fexpr->funcresulttype = result_type; fexpr->funcresulttype = result_type;
fexpr->funcretset = false; fexpr->funcretset = false;
fexpr->funcformat = COERCE_DONTCARE; /* doesn't matter */ 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->inputcollid = input_collid;
fexpr->args = args; fexpr->args = args;
fexpr->location = -1; fexpr->location = -1;
...@@ -4051,16 +4065,16 @@ inline_function(Oid funcid, Oid result_type, Oid input_collid, List *args, ...@@ -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 * 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. * or in other places where we expect exprCollation() to tell the truth.
*/ */
if (OidIsValid(input_collid)) if (OidIsValid(result_collid))
{ {
Oid exprcoll = exprCollation(newexpr); Oid exprcoll = exprCollation(newexpr);
if (OidIsValid(exprcoll) && exprcoll != input_collid) if (OidIsValid(exprcoll) && exprcoll != result_collid)
{ {
CollateExpr *newnode = makeNode(CollateExpr); CollateExpr *newnode = makeNode(CollateExpr);
newnode->arg = (Expr *) newexpr; newnode->arg = (Expr *) newexpr;
newnode->collOid = input_collid; newnode->collOid = result_collid;
newnode->location = -1; newnode->location = -1;
newexpr = (Node *) newnode; newexpr = (Node *) newnode;
...@@ -4165,7 +4179,8 @@ sql_inline_error_callback(void *arg) ...@@ -4165,7 +4179,8 @@ 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, int32 result_typmod) evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod,
Oid result_collation)
{ {
EState *estate; EState *estate;
ExprState *exprstate; ExprState *exprstate;
...@@ -4231,7 +4246,8 @@ evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod) ...@@ -4231,7 +4246,8 @@ evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod)
/* /*
* Make the constant result node. * 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, const_val, const_is_null,
resultTypByVal); resultTypByVal);
} }
......
...@@ -753,6 +753,7 @@ build_coercion_expression(Node *node, ...@@ -753,6 +753,7 @@ build_coercion_expression(Node *node,
/* Pass target typmod as an int4 constant */ /* Pass target typmod as an int4 constant */
cons = makeConst(INT4OID, cons = makeConst(INT4OID,
-1, -1,
InvalidOid,
sizeof(int32), sizeof(int32),
Int32GetDatum(targetTypMod), Int32GetDatum(targetTypMod),
false, false,
...@@ -766,6 +767,7 @@ build_coercion_expression(Node *node, ...@@ -766,6 +767,7 @@ build_coercion_expression(Node *node,
/* Pass it a boolean isExplicit parameter, too */ /* Pass it a boolean isExplicit parameter, too */
cons = makeConst(BOOLOID, cons = makeConst(BOOLOID,
-1, -1,
InvalidOid,
sizeof(bool), sizeof(bool),
BoolGetDatum(isExplicit), BoolGetDatum(isExplicit),
false, false,
...@@ -890,7 +892,8 @@ coerce_record_to_complex(ParseState *pstate, Node *node, ...@@ -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 * 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, -1)); newargs = lappend(newargs,
makeNullConst(INT4OID, -1, InvalidOid));
continue; continue;
} }
......
...@@ -347,6 +347,7 @@ transformArraySubscripts(ParseState *pstate, ...@@ -347,6 +347,7 @@ transformArraySubscripts(ParseState *pstate,
/* Make a constant 1 */ /* Make a constant 1 */
subexpr = (Node *) makeConst(INT4OID, subexpr = (Node *) makeConst(INT4OID,
-1, -1,
InvalidOid,
sizeof(int32), sizeof(int32),
Int32GetDatum(1), Int32GetDatum(1),
false, false,
...@@ -526,6 +527,7 @@ make_const(ParseState *pstate, Value *value, int location) ...@@ -526,6 +527,7 @@ make_const(ParseState *pstate, Value *value, int location)
/* return a null const */ /* return a null const */
con = makeConst(UNKNOWNOID, con = makeConst(UNKNOWNOID,
-1, -1,
InvalidOid,
-2, -2,
(Datum) 0, (Datum) 0,
true, true,
...@@ -540,6 +542,7 @@ make_const(ParseState *pstate, Value *value, int location) ...@@ -540,6 +542,7 @@ make_const(ParseState *pstate, Value *value, int location)
con = makeConst(typeid, con = makeConst(typeid,
-1, /* typmod -1 is OK for all cases */ -1, /* typmod -1 is OK for all cases */
InvalidOid, /* all cases are uncollatable types */
typelen, typelen,
val, val,
false, false,
......
...@@ -1870,7 +1870,8 @@ expandTupleDesc(TupleDesc tupdesc, Alias *eref, ...@@ -1870,7 +1870,8 @@ 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, -1)); *colvars = lappend(*colvars,
makeNullConst(INT4OID, -1, InvalidOid));
} }
} }
continue; continue;
......
...@@ -434,7 +434,8 @@ transformAssignedExpr(ParseState *pstate, ...@@ -434,7 +434,8 @@ 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, attrtypmod); colVar = (Node *) makeNullConst(attrtype, attrtypmod,
attrcollation);
} }
else else
{ {
......
...@@ -208,7 +208,7 @@ AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown) ...@@ -208,7 +208,7 @@ AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown)
* 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, -1); aliasvar = (Var *) makeNullConst(INT4OID, -1, InvalidOid);
} }
} }
newaliasvars = lappend(newaliasvars, aliasvar); newaliasvars = lappend(newaliasvars, aliasvar);
...@@ -719,6 +719,7 @@ rewriteTargetListIU(Query *parsetree, Relation target_relation, ...@@ -719,6 +719,7 @@ rewriteTargetListIU(Query *parsetree, Relation target_relation,
{ {
new_expr = (Node *) makeConst(att_tup->atttypid, new_expr = (Node *) makeConst(att_tup->atttypid,
-1, -1,
att_tup->attcollation,
att_tup->attlen, att_tup->attlen,
(Datum) 0, (Datum) 0,
true, /* isnull */ true, /* isnull */
...@@ -1082,6 +1083,7 @@ rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation, List *attrnos) ...@@ -1082,6 +1083,7 @@ rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation, List *attrnos)
{ {
new_expr = (Node *) makeConst(att_tup->atttypid, new_expr = (Node *) makeConst(att_tup->atttypid,
-1, -1,
att_tup->attcollation,
att_tup->attlen, att_tup->attlen,
(Datum) 0, (Datum) 0,
true, /* isnull */ true, /* isnull */
......
...@@ -1281,7 +1281,8 @@ ResolveNew_callback(Var *var, ...@@ -1281,7 +1281,8 @@ ResolveNew_callback(Var *var,
/* 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), var->vartypmod,
var->varcollid),
InvalidOid, -1, InvalidOid, -1,
var->vartype, var->vartype,
COERCE_IMPLICIT_CAST, COERCE_IMPLICIT_CAST,
......
...@@ -1686,6 +1686,7 @@ scalararraysel(PlannerInfo *root, ...@@ -1686,6 +1686,7 @@ scalararraysel(PlannerInfo *root,
Node *leftop; Node *leftop;
Node *rightop; Node *rightop;
Oid nominal_element_type; Oid nominal_element_type;
Oid nominal_element_collation;
RegProcedure oprsel; RegProcedure oprsel;
FmgrInfo oprselproc; FmgrInfo oprselproc;
Selectivity s1; Selectivity s1;
...@@ -1712,6 +1713,8 @@ scalararraysel(PlannerInfo *root, ...@@ -1712,6 +1713,8 @@ scalararraysel(PlannerInfo *root,
nominal_element_type = get_base_element_type(exprType(rightop)); nominal_element_type = get_base_element_type(exprType(rightop));
if (!OidIsValid(nominal_element_type)) if (!OidIsValid(nominal_element_type))
return (Selectivity) 0.5; /* probably shouldn't happen */ 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 */ /* look through any binary-compatible relabeling of rightop */
rightop = strip_array_coercion(rightop); rightop = strip_array_coercion(rightop);
...@@ -1759,6 +1762,7 @@ scalararraysel(PlannerInfo *root, ...@@ -1759,6 +1762,7 @@ scalararraysel(PlannerInfo *root,
args = list_make2(leftop, args = list_make2(leftop,
makeConst(nominal_element_type, makeConst(nominal_element_type,
-1, -1,
nominal_element_collation,
elmlen, elmlen,
elem_values[i], elem_values[i],
elem_nulls[i], elem_nulls[i],
...@@ -5616,9 +5620,39 @@ static Const * ...@@ -5616,9 +5620,39 @@ static Const *
string_to_const(const char *str, Oid datatype) string_to_const(const char *str, Oid datatype)
{ {
Datum conval = string_to_datum(str, 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); conval, false, false);
} }
...@@ -5635,7 +5669,7 @@ string_to_bytea_const(const char *str, size_t str_len) ...@@ -5635,7 +5669,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, -1, conval, false, false); return makeConst(BYTEAOID, -1, InvalidOid, -1, conval, false, false);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
......
...@@ -2084,6 +2084,7 @@ get_typdefault(Oid typid) ...@@ -2084,6 +2084,7 @@ get_typdefault(Oid typid)
/* Build a Const node containing the value */ /* Build a Const node containing the value */
expr = (Node *) makeConst(typid, expr = (Node *) makeConst(typid,
-1, -1,
type->typcollation,
type->typlen, type->typlen,
datum, datum,
false, false,
......
...@@ -48,12 +48,13 @@ extern FromExpr *makeFromExpr(List *fromlist, Node *quals); ...@@ -48,12 +48,13 @@ extern FromExpr *makeFromExpr(List *fromlist, Node *quals);
extern Const *makeConst(Oid consttype, extern Const *makeConst(Oid consttype,
int32 consttypmod, int32 consttypmod,
Oid constcollid,
int constlen, int constlen,
Datum constvalue, Datum constvalue,
bool constisnull, bool constisnull,
bool constbyval); bool constbyval);
extern Const *makeNullConst(Oid consttype, int32 consttypmod); extern Const *makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid);
extern Node *makeBoolConst(bool value, bool isnull); extern Node *makeBoolConst(bool value, bool isnull);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment