@@ -69,13 +69,18 @@ static List *rewriteTargetListIU(List *targetList,
69
69
CmdType commandType ,
70
70
OverridingKind override ,
71
71
Relation target_relation ,
72
- int result_rti );
72
+ int result_rti ,
73
+ RangeTblEntry * values_rte ,
74
+ int values_rte_index ,
75
+ Bitmapset * * unused_values_attrnos );
73
76
static TargetEntry * process_matched_tle (TargetEntry * src_tle ,
74
77
TargetEntry * prior_tle ,
75
78
const char * attrName );
76
79
static Node * get_assignment_input (Node * node );
80
+ static Bitmapset * findDefaultOnlyColumns (RangeTblEntry * rte );
77
81
static bool rewriteValuesRTE (Query * parsetree , RangeTblEntry * rte , int rti ,
78
- Relation target_relation , bool force_nulls );
82
+ Relation target_relation , bool force_nulls ,
83
+ Bitmapset * unused_cols );
79
84
static void markQueryForLocking (Query * qry , Node * jtnode ,
80
85
LockClauseStrength strength , LockWaitPolicy waitPolicy ,
81
86
bool pushedDown );
@@ -708,13 +713,25 @@ adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
708
713
* is incorrect by this light, since child relations might have different
709
714
* column ordering, but the planner will fix things by re-sorting the tlist
710
715
* for each child.)
716
+ *
717
+ * If values_rte is non-NULL (i.e., we are doing a multi-row INSERT using
718
+ * values from a VALUES RTE), we populate *unused_values_attrnos with the
719
+ * attribute numbers of any unused columns from the VALUES RTE. This can
720
+ * happen for identity and generated columns whose targetlist entries are
721
+ * replaced with generated expressions (if INSERT ... OVERRIDING USER VALUE is
722
+ * used, or all the values to be inserted are DEFAULT). This information is
723
+ * required by rewriteValuesRTE() to handle any DEFAULT items in the unused
724
+ * columns. The caller must have initialized *unused_values_attrnos to NULL.
711
725
*/
712
726
static List *
713
727
rewriteTargetListIU (List * targetList ,
714
728
CmdType commandType ,
715
729
OverridingKind override ,
716
730
Relation target_relation ,
717
- int result_rti )
731
+ int result_rti ,
732
+ RangeTblEntry * values_rte ,
733
+ int values_rte_index ,
734
+ Bitmapset * * unused_values_attrnos )
718
735
{
719
736
TargetEntry * * new_tles ;
720
737
List * new_tlist = NIL ;
@@ -724,6 +741,7 @@ rewriteTargetListIU(List *targetList,
724
741
next_junk_attrno ,
725
742
numattrs ;
726
743
ListCell * temp ;
744
+ Bitmapset * default_only_cols = NULL ;
727
745
728
746
/*
729
747
* We process the normal (non-junk) attributes by scanning the input tlist
@@ -803,30 +821,106 @@ rewriteTargetListIU(List *targetList,
803
821
804
822
if (commandType == CMD_INSERT )
805
823
{
824
+ int values_attrno = 0 ;
825
+
826
+ /* Source attribute number for values that come from a VALUES RTE */
827
+ if (values_rte && new_tle && IsA (new_tle -> expr , Var ))
828
+ {
829
+ Var * var = (Var * ) new_tle -> expr ;
830
+
831
+ if (var -> varno == values_rte_index )
832
+ values_attrno = var -> varattno ;
833
+ }
834
+
835
+ /*
836
+ * Can only insert DEFAULT into GENERATED ALWAYS identity columns,
837
+ * unless either OVERRIDING USER VALUE or OVERRIDING SYSTEM VALUE
838
+ * is specified.
839
+ */
806
840
if (att_tup -> attidentity == ATTRIBUTE_IDENTITY_ALWAYS && !apply_default )
807
841
{
808
842
if (override == OVERRIDING_USER_VALUE )
809
843
apply_default = true;
810
844
else if (override != OVERRIDING_SYSTEM_VALUE )
811
- ereport (ERROR ,
812
- (errcode (ERRCODE_GENERATED_ALWAYS ),
813
- errmsg ("cannot insert into column \"%s\"" , NameStr (att_tup -> attname )),
814
- errdetail ("Column \"%s\" is an identity column defined as GENERATED ALWAYS." ,
815
- NameStr (att_tup -> attname )),
816
- errhint ("Use OVERRIDING SYSTEM VALUE to override." )));
845
+ {
846
+ /*
847
+ * If this column's values come from a VALUES RTE, test
848
+ * whether it contains only SetToDefault items. Since the
849
+ * VALUES list might be quite large, we arrange to only
850
+ * scan it once.
851
+ */
852
+ if (values_attrno != 0 )
853
+ {
854
+ if (default_only_cols == NULL )
855
+ default_only_cols = findDefaultOnlyColumns (values_rte );
856
+
857
+ if (bms_is_member (values_attrno , default_only_cols ))
858
+ apply_default = true;
859
+ }
860
+
861
+ if (!apply_default )
862
+ ereport (ERROR ,
863
+ (errcode (ERRCODE_GENERATED_ALWAYS ),
864
+ errmsg ("cannot insert into column \"%s\"" ,
865
+ NameStr (att_tup -> attname )),
866
+ errdetail ("Column \"%s\" is an identity column defined as GENERATED ALWAYS." ,
867
+ NameStr (att_tup -> attname )),
868
+ errhint ("Use OVERRIDING SYSTEM VALUE to override." )));
869
+ }
817
870
}
818
871
819
- if (att_tup -> attidentity == ATTRIBUTE_IDENTITY_BY_DEFAULT && override == OVERRIDING_USER_VALUE )
872
+ /*
873
+ * Although inserting into a GENERATED BY DEFAULT identity column
874
+ * is allowed, apply the default if OVERRIDING USER VALUE is
875
+ * specified.
876
+ */
877
+ if (att_tup -> attidentity == ATTRIBUTE_IDENTITY_BY_DEFAULT &&
878
+ override == OVERRIDING_USER_VALUE )
820
879
apply_default = true;
821
880
881
+ /*
882
+ * Can only insert DEFAULT into generated columns, regardless of
883
+ * any OVERRIDING clauses.
884
+ */
822
885
if (att_tup -> attgenerated && !apply_default )
823
- ereport (ERROR ,
824
- (errcode (ERRCODE_SYNTAX_ERROR ),
825
- errmsg ("cannot insert into column \"%s\"" , NameStr (att_tup -> attname )),
826
- errdetail ("Column \"%s\" is a generated column." ,
827
- NameStr (att_tup -> attname ))));
886
+ {
887
+ /*
888
+ * If this column's values come from a VALUES RTE, test
889
+ * whether it contains only SetToDefault items, as above.
890
+ */
891
+ if (values_attrno != 0 )
892
+ {
893
+ if (default_only_cols == NULL )
894
+ default_only_cols = findDefaultOnlyColumns (values_rte );
895
+
896
+ if (bms_is_member (values_attrno , default_only_cols ))
897
+ apply_default = true;
898
+ }
899
+
900
+ if (!apply_default )
901
+ ereport (ERROR ,
902
+ (errcode (ERRCODE_SYNTAX_ERROR ),
903
+ errmsg ("cannot insert into column \"%s\"" ,
904
+ NameStr (att_tup -> attname )),
905
+ errdetail ("Column \"%s\" is a generated column." ,
906
+ NameStr (att_tup -> attname ))));
907
+ }
908
+
909
+ /*
910
+ * For an INSERT from a VALUES RTE, return the attribute numbers
911
+ * of any VALUES columns that will no longer be used (due to the
912
+ * targetlist entry being replaced by a default expression).
913
+ */
914
+ if (values_attrno != 0 && apply_default && unused_values_attrnos )
915
+ * unused_values_attrnos = bms_add_member (* unused_values_attrnos ,
916
+ values_attrno );
828
917
}
829
918
919
+ /*
920
+ * Updates to identity and generated columns follow the same rules as
921
+ * above, except that UPDATE doesn't admit OVERRIDING clauses. Also,
922
+ * the source can't be a VALUES RTE, so we needn't consider that.
923
+ */
830
924
if (commandType == CMD_UPDATE )
831
925
{
832
926
if (att_tup -> attidentity == ATTRIBUTE_IDENTITY_ALWAYS && new_tle && !apply_default )
@@ -1219,6 +1313,62 @@ searchForDefault(RangeTblEntry *rte)
1219
1313
return false;
1220
1314
}
1221
1315
1316
+
1317
+ /*
1318
+ * Search a VALUES RTE for columns that contain only SetToDefault items,
1319
+ * returning a Bitmapset containing the attribute numbers of any such columns.
1320
+ */
1321
+ static Bitmapset *
1322
+ findDefaultOnlyColumns (RangeTblEntry * rte )
1323
+ {
1324
+ Bitmapset * default_only_cols = NULL ;
1325
+ ListCell * lc ;
1326
+
1327
+ foreach (lc , rte -> values_lists )
1328
+ {
1329
+ List * sublist = (List * ) lfirst (lc );
1330
+ ListCell * lc2 ;
1331
+ int i ;
1332
+
1333
+ if (default_only_cols == NULL )
1334
+ {
1335
+ /* Populate the initial result bitmap from the first row */
1336
+ i = 0 ;
1337
+ foreach (lc2 , sublist )
1338
+ {
1339
+ Node * col = (Node * ) lfirst (lc2 );
1340
+
1341
+ i ++ ;
1342
+ if (IsA (col , SetToDefault ))
1343
+ default_only_cols = bms_add_member (default_only_cols , i );
1344
+ }
1345
+ }
1346
+ else
1347
+ {
1348
+ /* Update the result bitmap from this next row */
1349
+ i = 0 ;
1350
+ foreach (lc2 , sublist )
1351
+ {
1352
+ Node * col = (Node * ) lfirst (lc2 );
1353
+
1354
+ i ++ ;
1355
+ if (!IsA (col , SetToDefault ))
1356
+ default_only_cols = bms_del_member (default_only_cols , i );
1357
+ }
1358
+ }
1359
+
1360
+ /*
1361
+ * If no column in the rows read so far contains only DEFAULT items,
1362
+ * we are done.
1363
+ */
1364
+ if (bms_is_empty (default_only_cols ))
1365
+ break ;
1366
+ }
1367
+
1368
+ return default_only_cols ;
1369
+ }
1370
+
1371
+
1222
1372
/*
1223
1373
* When processing INSERT ... VALUES with a VALUES RTE (ie, multiple VALUES
1224
1374
* lists), we have to replace any DEFAULT items in the VALUES lists with
@@ -1246,19 +1396,31 @@ searchForDefault(RangeTblEntry *rte)
1246
1396
* an insert into an auto-updatable view, and the product queries are inserts
1247
1397
* into a rule-updatable view.
1248
1398
*
1399
+ * Finally, if a DEFAULT item is found in a column mentioned in unused_cols,
1400
+ * it is explicitly set to NULL. This happens for columns in the VALUES RTE
1401
+ * whose corresponding targetlist entries have already been replaced with the
1402
+ * relation's default expressions, so that any values in those columns of the
1403
+ * VALUES RTE are no longer used. This can happen for identity and generated
1404
+ * columns (if INSERT ... OVERRIDING USER VALUE is used, or all the values to
1405
+ * be inserted are DEFAULT). In principle we could replace all entries in
1406
+ * such a column with NULL, whether DEFAULT or not; but it doesn't seem worth
1407
+ * the trouble.
1408
+ *
1249
1409
* Note that we may have subscripted or field assignment targetlist entries,
1250
1410
* as well as more complex expressions from already-replaced DEFAULT items if
1251
1411
* we have recursed to here for an auto-updatable view. However, it ought to
1252
- * be impossible for such entries to have DEFAULTs assigned to them --- we
1253
- * should only have to replace DEFAULT items for targetlist entries that
1254
- * contain simple Vars referencing the VALUES RTE.
1412
+ * be impossible for such entries to have DEFAULTs assigned to them, except
1413
+ * for unused columns, as described above --- we should only have to replace
1414
+ * DEFAULT items for targetlist entries that contain simple Vars referencing
1415
+ * the VALUES RTE, or which are no longer referred to by the targetlist.
1255
1416
*
1256
1417
* Returns true if all DEFAULT items were replaced, and false if some were
1257
1418
* left untouched.
1258
1419
*/
1259
1420
static bool
1260
1421
rewriteValuesRTE (Query * parsetree , RangeTblEntry * rte , int rti ,
1261
- Relation target_relation , bool force_nulls )
1422
+ Relation target_relation , bool force_nulls ,
1423
+ Bitmapset * unused_cols )
1262
1424
{
1263
1425
List * newValues ;
1264
1426
ListCell * lc ;
@@ -1282,8 +1444,8 @@ rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti,
1282
1444
* Scan the targetlist for entries referring to the VALUES RTE, and note
1283
1445
* the target attributes. As noted above, we should only need to do this
1284
1446
* for targetlist entries containing simple Vars --- nothing else in the
1285
- * VALUES RTE should contain DEFAULT items, and we complain if such a
1286
- * thing does occur.
1447
+ * VALUES RTE should contain DEFAULT items (except possibly for unused
1448
+ * columns), and we complain if such a thing does occur.
1287
1449
*/
1288
1450
numattrs = list_length (linitial (rte -> values_lists ));
1289
1451
attrnos = (int * ) palloc0 (numattrs * sizeof (int ));
@@ -1370,6 +1532,22 @@ rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti,
1370
1532
Form_pg_attribute att_tup ;
1371
1533
Node * new_expr ;
1372
1534
1535
+ /*
1536
+ * If this column isn't used, just replace the DEFAULT with
1537
+ * NULL (attrno will be 0 in this case because the targetlist
1538
+ * entry will have been replaced by the default expression).
1539
+ */
1540
+ if (bms_is_member (i , unused_cols ))
1541
+ {
1542
+ SetToDefault * def = (SetToDefault * ) col ;
1543
+
1544
+ newList = lappend (newList ,
1545
+ makeNullConst (def -> typeId ,
1546
+ def -> typeMod ,
1547
+ def -> collation ));
1548
+ continue ;
1549
+ }
1550
+
1373
1551
if (attrno == 0 )
1374
1552
elog (ERROR , "cannot set value in column %d to DEFAULT" , i );
1375
1553
att_tup = TupleDescAttr (target_relation -> rd_att , attrno - 1 );
@@ -3614,15 +3792,21 @@ RewriteQuery(Query *parsetree, List *rewrite_events)
3614
3792
3615
3793
if (values_rte )
3616
3794
{
3795
+ Bitmapset * unused_values_attrnos = NULL ;
3796
+
3617
3797
/* Process the main targetlist ... */
3618
3798
parsetree -> targetList = rewriteTargetListIU (parsetree -> targetList ,
3619
3799
parsetree -> commandType ,
3620
3800
parsetree -> override ,
3621
3801
rt_entry_relation ,
3622
- parsetree -> resultRelation );
3802
+ parsetree -> resultRelation ,
3803
+ values_rte ,
3804
+ values_rte_index ,
3805
+ & unused_values_attrnos );
3623
3806
/* ... and the VALUES expression lists */
3624
3807
if (!rewriteValuesRTE (parsetree , values_rte , values_rte_index ,
3625
- rt_entry_relation , false))
3808
+ rt_entry_relation , false,
3809
+ unused_values_attrnos ))
3626
3810
defaults_remaining = true;
3627
3811
}
3628
3812
else
@@ -3633,7 +3817,8 @@ RewriteQuery(Query *parsetree, List *rewrite_events)
3633
3817
parsetree -> commandType ,
3634
3818
parsetree -> override ,
3635
3819
rt_entry_relation ,
3636
- parsetree -> resultRelation );
3820
+ parsetree -> resultRelation ,
3821
+ NULL , 0 , NULL );
3637
3822
}
3638
3823
3639
3824
if (parsetree -> onConflict &&
@@ -3644,7 +3829,8 @@ RewriteQuery(Query *parsetree, List *rewrite_events)
3644
3829
CMD_UPDATE ,
3645
3830
parsetree -> override ,
3646
3831
rt_entry_relation ,
3647
- parsetree -> resultRelation );
3832
+ parsetree -> resultRelation ,
3833
+ NULL , 0 , NULL );
3648
3834
}
3649
3835
}
3650
3836
else if (event == CMD_UPDATE )
@@ -3654,7 +3840,8 @@ RewriteQuery(Query *parsetree, List *rewrite_events)
3654
3840
parsetree -> commandType ,
3655
3841
parsetree -> override ,
3656
3842
rt_entry_relation ,
3657
- parsetree -> resultRelation );
3843
+ parsetree -> resultRelation ,
3844
+ NULL , 0 , NULL );
3658
3845
3659
3846
/* Also populate extraUpdatedCols (for generated columns) */
3660
3847
fill_extraUpdatedCols (rt_entry , rt_entry_relation );
@@ -3704,7 +3891,8 @@ RewriteQuery(Query *parsetree, List *rewrite_events)
3704
3891
3705
3892
rewriteValuesRTE (pt , values_rte , values_rte_index ,
3706
3893
rt_entry_relation ,
3707
- true); /* Force remaining defaults to NULL */
3894
+ true, /* Force remaining defaults to NULL */
3895
+ NULL );
3708
3896
}
3709
3897
}
3710
3898
0 commit comments