OSDN Git Service

Pass collation to makeConst() instead of looking it up internally.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 26 Mar 2011 00:10:42 +0000 (20:10 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 26 Mar 2011 00:10:42 +0000 (20:10 -0400)
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.

18 files changed:
src/backend/commands/tablecmds.c
src/backend/executor/execQual.c
src/backend/executor/functions.c
src/backend/nodes/makefuncs.c
src/backend/optimizer/path/indxpath.c
src/backend/optimizer/plan/planagg.c
src/backend/optimizer/prep/preptlist.c
src/backend/optimizer/prep/prepunion.c
src/backend/optimizer/util/clauses.c
src/backend/parser/parse_coerce.c
src/backend/parser/parse_node.c
src/backend/parser/parse_relation.c
src/backend/parser/parse_target.c
src/backend/rewrite/rewriteHandler.c
src/backend/rewrite/rewriteManip.c
src/backend/utils/adt/selfuncs.c
src/backend/utils/cache/lsyscache.c
src/include/nodes/makefuncs.h

index 596cd86..d7573b8 100644 (file)
@@ -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,
index e410818..c153ca0 100644 (file)
@@ -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);
index ce3b77b..70d126c 100644 (file)
@@ -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 */
index 41e597c..4d2eccf 100644 (file)
@@ -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);
 }
 
index 925155c..ecae57b 100644 (file)
@@ -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);
 }
index 3920370..f2ddf2a 100644 (file)
@@ -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);
 
index 63447aa..4ba8921 100644 (file)
@@ -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 */
index 606e5fe..e15a862 100644 (file)
@@ -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,
index 0fddbae..1a63146 100644 (file)
@@ -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);
 }
index 9b59b03..cc03f9f 100644 (file)
@@ -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;
                }
 
index 2c76c55..07257ac 100644 (file)
@@ -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,
index 488b142..7bfafdb 100644 (file)
@@ -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;
index 5507835..8e92b99 100644 (file)
@@ -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
                {
index 87d3917..a695b01 100644 (file)
@@ -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 */
index 49a6df0..d3985b2 100644 (file)
@@ -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,
index 33f300b..c757fcb 100644 (file)
@@ -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);
 }
 
 /*-------------------------------------------------------------------------
index 6af2342..6bcaf30 100644 (file)
@@ -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,
index ead7c40..152cb0d 100644 (file)
@@ -48,12 +48,13 @@ extern FromExpr *makeFromExpr(List *fromlist, Node *quals);
 
 extern Const *makeConst(Oid consttype,
                  int32 consttypmod,
+                 Oid constcollid,
                  int constlen,
                  Datum constvalue,
                  bool constisnull,
                  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);