@@ -536,7 +536,9 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
536
536
* RTE.
537
537
*/
538
538
List * exprsLists = NIL ;
539
+ List * collations = NIL ;
539
540
int sublist_length = -1 ;
541
+ int i ;
540
542
541
543
foreach (lc , selectStmt -> valuesLists )
542
544
{
@@ -573,13 +575,26 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
573
575
* We must assign collations now because assign_query_collations
574
576
* doesn't process rangetable entries. We just assign all the
575
577
* 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.)
577
585
*/
578
586
assign_list_collations (pstate , sublist );
579
587
580
588
exprsLists = lappend (exprsLists , sublist );
581
589
}
582
590
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
+
583
598
/*
584
599
* There mustn't have been any table references in the expressions,
585
600
* else strange things would happen, like Cartesian products of those
@@ -610,7 +625,8 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
610
625
/*
611
626
* Generate the VALUES RTE
612
627
*/
613
- rte = addRangeTableEntryForValues (pstate , exprsLists , NULL , true);
628
+ rte = addRangeTableEntryForValues (pstate , exprsLists , collations ,
629
+ NULL , true);
614
630
rtr = makeNode (RangeTblRef );
615
631
/* assume new rte is at end */
616
632
rtr -> rtindex = list_length (pstate -> p_rtable );
@@ -989,11 +1005,10 @@ static Query *
989
1005
transformValuesClause (ParseState * pstate , SelectStmt * stmt )
990
1006
{
991
1007
Query * qry = makeNode (Query );
992
- List * exprsLists = NIL ;
1008
+ List * exprsLists ;
1009
+ List * collations ;
993
1010
List * * colexprs = NULL ;
994
- Oid * coltypes = NULL ;
995
1011
int sublist_length = -1 ;
996
- List * newExprsLists ;
997
1012
RangeTblEntry * rte ;
998
1013
RangeTblRef * rtr ;
999
1014
ListCell * lc ;
@@ -1021,9 +1036,13 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
1021
1036
}
1022
1037
1023
1038
/*
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.
1027
1046
*/
1028
1047
foreach (lc , stmt -> valuesLists )
1029
1048
{
@@ -1041,9 +1060,8 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
1041
1060
{
1042
1061
/* Remember post-transformation length of first sublist */
1043
1062
sublist_length = list_length (sublist );
1044
- /* and allocate arrays for per-column info */
1063
+ /* and allocate array for per-column lists */
1045
1064
colexprs = (List * * ) palloc0 (sublist_length * sizeof (List * ));
1046
- coltypes = (Oid * ) palloc0 (sublist_length * sizeof (Oid ));
1047
1065
}
1048
1066
else if (sublist_length != list_length (sublist ))
1049
1067
{
@@ -1054,8 +1072,6 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
1054
1072
exprLocation ((Node * ) sublist ))));
1055
1073
}
1056
1074
1057
- exprsLists = lappend (exprsLists , sublist );
1058
-
1059
1075
/* Check for DEFAULT and build per-column expression lists */
1060
1076
i = 0 ;
1061
1077
foreach (lc2 , sublist )
@@ -1070,48 +1086,77 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
1070
1086
colexprs [i ] = lappend (colexprs [i ], col );
1071
1087
i ++ ;
1072
1088
}
1089
+
1090
+ /* Release sub-list's cells to save memory */
1091
+ list_free (sublist );
1073
1092
}
1074
1093
1075
1094
/*
1076
1095
* 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.
1078
1107
*/
1108
+ collations = NIL ;
1079
1109
for (i = 0 ; i < sublist_length ; i ++ )
1080
1110
{
1081
- coltypes [ i ] = select_common_type ( pstate , colexprs [ i ], "VALUES" , NULL ) ;
1082
- }
1111
+ Oid coltype ;
1112
+ Oid colcoll ;
1083
1113
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 );
1089
1115
1090
- i = 0 ;
1091
- foreach (lc2 , sublist )
1116
+ foreach (lc , colexprs [i ])
1092
1117
{
1093
- Node * col = (Node * ) lfirst (lc2 );
1118
+ Node * col = (Node * ) lfirst (lc );
1094
1119
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 ;
1098
1122
}
1099
1123
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
+ }
1107
1128
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 ]);
1109
1153
}
1110
1154
1111
1155
/*
1112
1156
* Generate the VALUES RTE
1113
1157
*/
1114
- rte = addRangeTableEntryForValues (pstate , newExprsLists , NULL , true);
1158
+ rte = addRangeTableEntryForValues (pstate , exprsLists , collations ,
1159
+ NULL , true);
1115
1160
rtr = makeNode (RangeTblRef );
1116
1161
/* assume new rte is at end */
1117
1162
rtr -> rtindex = list_length (pstate -> p_rtable );
@@ -1164,7 +1209,7 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
1164
1209
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1165
1210
errmsg ("VALUES must not contain table references" ),
1166
1211
parser_errposition (pstate ,
1167
- locate_var_of_level ((Node * ) newExprsLists , 0 ))));
1212
+ locate_var_of_level ((Node * ) exprsLists , 0 ))));
1168
1213
1169
1214
/*
1170
1215
* Another thing we can't currently support is NEW/OLD references in rules
@@ -1173,13 +1218,13 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
1173
1218
* This is a shame. FIXME
1174
1219
*/
1175
1220
if (list_length (pstate -> p_rtable ) != 1 &&
1176
- contain_vars_of_level ((Node * ) newExprsLists , 0 ))
1221
+ contain_vars_of_level ((Node * ) exprsLists , 0 ))
1177
1222
ereport (ERROR ,
1178
1223
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1179
1224
errmsg ("VALUES must not contain OLD or NEW references" ),
1180
1225
errhint ("Use SELECT ... UNION ALL ... instead." ),
1181
1226
parser_errposition (pstate ,
1182
- locate_var_of_level ((Node * ) newExprsLists , 0 ))));
1227
+ locate_var_of_level ((Node * ) exprsLists , 0 ))));
1183
1228
1184
1229
qry -> rtable = pstate -> p_rtable ;
1185
1230
qry -> jointree = makeFromExpr (pstate -> p_joinlist , NULL );
@@ -1191,13 +1236,13 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
1191
1236
(errcode (ERRCODE_GROUPING_ERROR ),
1192
1237
errmsg ("cannot use aggregate function in VALUES" ),
1193
1238
parser_errposition (pstate ,
1194
- locate_agg_of_level ((Node * ) newExprsLists , 0 ))));
1239
+ locate_agg_of_level ((Node * ) exprsLists , 0 ))));
1195
1240
if (pstate -> p_hasWindowFuncs )
1196
1241
ereport (ERROR ,
1197
1242
(errcode (ERRCODE_WINDOWING_ERROR ),
1198
1243
errmsg ("cannot use window function in VALUES" ),
1199
1244
parser_errposition (pstate ,
1200
- locate_windowfunc ((Node * ) newExprsLists ))));
1245
+ locate_windowfunc ((Node * ) exprsLists ))));
1201
1246
1202
1247
assign_query_collations (pstate , qry );
1203
1248
0 commit comments