@@ -536,7 +536,9 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
536536 * RTE.
537537 */
538538List * exprsLists = NIL ;
539+ List * collations = NIL ;
539540int sublist_length = -1 ;
541+ int i ;
540542
541543foreach (lc ,selectStmt -> valuesLists )
542544{
@@ -573,13 +575,26 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
573575 * We must assign collations now because assign_query_collations
574576 * doesn't process rangetable entries. We just assign all the
575577 * collations independently in each row, and don't worry about
576- * whether they are consistent vertically either.
578+ * whether they are consistent vertically. The outer INSERT query
579+ * isn't going to care about the collations of the VALUES columns,
580+ * so it's not worth the effort to identify a common collation for
581+ * each one here. (But note this does have one user-visible
582+ * consequence: INSERT ... VALUES won't complain about conflicting
583+ * explicit COLLATEs in a column, whereas the same VALUES
584+ * construct in another context would complain.)
577585 */
578586assign_list_collations (pstate ,sublist );
579587
580588exprsLists = lappend (exprsLists ,sublist );
581589}
582590
591+ /*
592+ * Although we don't really need collation info, let's just make sure
593+ * we provide a correctly-sized list in the VALUES RTE.
594+ */
595+ for (i = 0 ;i < sublist_length ;i ++ )
596+ collations = lappend_oid (collations ,InvalidOid );
597+
583598/*
584599 * There mustn't have been any table references in the expressions,
585600 * else strange things would happen, like Cartesian products of those
@@ -610,7 +625,8 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
610625/*
611626 * Generate the VALUES RTE
612627 */
613- rte = addRangeTableEntryForValues (pstate ,exprsLists ,NULL , true);
628+ rte = addRangeTableEntryForValues (pstate ,exprsLists ,collations ,
629+ NULL , true);
614630rtr = makeNode (RangeTblRef );
615631/* assume new rte is at end */
616632rtr -> rtindex = list_length (pstate -> p_rtable );
@@ -989,11 +1005,10 @@ static Query *
9891005transformValuesClause (ParseState * pstate ,SelectStmt * stmt )
9901006{
9911007Query * qry = makeNode (Query );
992- List * exprsLists = NIL ;
1008+ List * exprsLists ;
1009+ List * collations ;
9931010List * * colexprs = NULL ;
994- Oid * coltypes = NULL ;
9951011int sublist_length = -1 ;
996- List * newExprsLists ;
9971012RangeTblEntry * rte ;
9981013RangeTblRef * rtr ;
9991014ListCell * lc ;
@@ -1021,9 +1036,13 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
10211036}
10221037
10231038/*
1024- * For each row of VALUES, transform the raw expressions and gather type
1025- * information. This is also a handy place to reject DEFAULT nodes, which
1026- * the grammar allows for simplicity.
1039+ * For each row of VALUES, transform the raw expressions. This is also a
1040+ * handy place to reject DEFAULT nodes, which the grammar allows for
1041+ * simplicity.
1042+ *
1043+ * Note that the intermediate representation we build is column-organized
1044+ * not row-organized. That simplifies the type and collation processing
1045+ * below.
10271046 */
10281047foreach (lc ,stmt -> valuesLists )
10291048{
@@ -1041,9 +1060,8 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
10411060{
10421061/* Remember post-transformation length of first sublist */
10431062sublist_length = list_length (sublist );
1044- /* and allocatearrays for per-columninfo */
1063+ /* and allocatearray for per-columnlists */
10451064colexprs = (List * * )palloc0 (sublist_length * sizeof (List * ));
1046- coltypes = (Oid * )palloc0 (sublist_length * sizeof (Oid ));
10471065}
10481066else if (sublist_length != list_length (sublist ))
10491067{
@@ -1054,8 +1072,6 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
10541072exprLocation ((Node * )sublist ))));
10551073}
10561074
1057- exprsLists = lappend (exprsLists ,sublist );
1058-
10591075/* Check for DEFAULT and build per-column expression lists */
10601076i = 0 ;
10611077foreach (lc2 ,sublist )
@@ -1070,48 +1086,77 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
10701086colexprs [i ]= lappend (colexprs [i ],col );
10711087i ++ ;
10721088}
1089+
1090+ /* Release sub-list's cells to save memory */
1091+ list_free (sublist );
10731092}
10741093
10751094/*
10761095 * Now resolve the common types of the columns, and coerce everything to
1077- * those types.
1096+ * those types. Then identify the common collation, if any, of each
1097+ * column.
1098+ *
1099+ * We must do collation processing now because (1) assign_query_collations
1100+ * doesn't process rangetable entries, and (2) we need to label the VALUES
1101+ * RTE with column collations for use in the outer query. We don't
1102+ * consider conflict of implicit collations to be an error here; instead
1103+ * the column will just show InvalidOid as its collation, and you'll get
1104+ * a failure later if that results in failure to resolve a collation.
1105+ *
1106+ * Note we modify the per-column expression lists in-place.
10781107 */
1108+ collations = NIL ;
10791109for (i = 0 ;i < sublist_length ;i ++ )
10801110{
1081- coltypes [ i ] = select_common_type ( pstate , colexprs [ i ], "VALUES" , NULL ) ;
1082- }
1111+ Oid coltype ;
1112+ Oid colcoll ;
10831113
1084- newExprsLists = NIL ;
1085- foreach (lc ,exprsLists )
1086- {
1087- List * sublist = (List * )lfirst (lc );
1088- List * newsublist = NIL ;
1114+ coltype = select_common_type (pstate ,colexprs [i ],"VALUES" ,NULL );
10891115
1090- i = 0 ;
1091- foreach (lc2 ,sublist )
1116+ foreach (lc ,colexprs [i ])
10921117{
1093- Node * col = (Node * )lfirst (lc2 );
1118+ Node * col = (Node * )lfirst (lc );
10941119
1095- col = coerce_to_common_type (pstate ,col ,coltypes [i ],"VALUES" );
1096- newsublist = lappend (newsublist ,col );
1097- i ++ ;
1120+ col = coerce_to_common_type (pstate ,col ,coltype ,"VALUES" );
1121+ lfirst (lc )= (void * )col ;
10981122}
10991123
1100- /*
1101- * We must assign collations now because assign_query_collations
1102- * doesn't process rangetable entries. We just assign all the
1103- * collations independently in each row, and don't worry about whether
1104- * they are consistent vertically either.
1105- */
1106- assign_list_collations (pstate ,newsublist );
1124+ colcoll = select_common_collation (pstate ,colexprs [i ], true);
1125+
1126+ collations = lappend_oid (collations ,colcoll );
1127+ }
11071128
1108- newExprsLists = lappend (newExprsLists ,newsublist );
1129+ /*
1130+ * Finally, rearrange the coerced expressions into row-organized lists.
1131+ */
1132+ exprsLists = NIL ;
1133+ foreach (lc ,colexprs [0 ])
1134+ {
1135+ Node * col = (Node * )lfirst (lc );
1136+ List * sublist ;
1137+
1138+ sublist = list_make1 (col );
1139+ exprsLists = lappend (exprsLists ,sublist );
1140+ }
1141+ list_free (colexprs [0 ]);
1142+ for (i = 1 ;i < sublist_length ;i ++ )
1143+ {
1144+ forboth (lc ,colexprs [i ],lc2 ,exprsLists )
1145+ {
1146+ Node * col = (Node * )lfirst (lc );
1147+ List * sublist = lfirst (lc2 );
1148+
1149+ /* sublist pointer in exprsLists won't need adjustment */
1150+ (void )lappend (sublist ,col );
1151+ }
1152+ list_free (colexprs [i ]);
11091153}
11101154
11111155/*
11121156 * Generate the VALUES RTE
11131157 */
1114- rte = addRangeTableEntryForValues (pstate ,newExprsLists ,NULL , true);
1158+ rte = addRangeTableEntryForValues (pstate ,exprsLists ,collations ,
1159+ NULL , true);
11151160rtr = makeNode (RangeTblRef );
11161161/* assume new rte is at end */
11171162rtr -> rtindex = list_length (pstate -> p_rtable );
@@ -1164,7 +1209,7 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
11641209(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
11651210errmsg ("VALUES must not contain table references" ),
11661211parser_errposition (pstate ,
1167- locate_var_of_level ((Node * )newExprsLists ,0 ))));
1212+ locate_var_of_level ((Node * )exprsLists ,0 ))));
11681213
11691214/*
11701215 * Another thing we can't currently support is NEW/OLD references in rules
@@ -1173,13 +1218,13 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
11731218 * This is a shame. FIXME
11741219 */
11751220if (list_length (pstate -> p_rtable )!= 1 &&
1176- contain_vars_of_level ((Node * )newExprsLists ,0 ))
1221+ contain_vars_of_level ((Node * )exprsLists ,0 ))
11771222ereport (ERROR ,
11781223(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
11791224errmsg ("VALUES must not contain OLD or NEW references" ),
11801225errhint ("Use SELECT ... UNION ALL ... instead." ),
11811226parser_errposition (pstate ,
1182- locate_var_of_level ((Node * )newExprsLists ,0 ))));
1227+ locate_var_of_level ((Node * )exprsLists ,0 ))));
11831228
11841229qry -> rtable = pstate -> p_rtable ;
11851230qry -> jointree = makeFromExpr (pstate -> p_joinlist ,NULL );
@@ -1191,13 +1236,13 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
11911236(errcode (ERRCODE_GROUPING_ERROR ),
11921237errmsg ("cannot use aggregate function in VALUES" ),
11931238parser_errposition (pstate ,
1194- locate_agg_of_level ((Node * )newExprsLists ,0 ))));
1239+ locate_agg_of_level ((Node * )exprsLists ,0 ))));
11951240if (pstate -> p_hasWindowFuncs )
11961241ereport (ERROR ,
11971242(errcode (ERRCODE_WINDOWING_ERROR ),
11981243errmsg ("cannot use window function in VALUES" ),
11991244parser_errposition (pstate ,
1200- locate_windowfunc ((Node * )newExprsLists ))));
1245+ locate_windowfunc ((Node * )exprsLists ))));
12011246
12021247assign_query_collations (pstate ,qry );
12031248