fix-default-handling-for-insert-select-rule.patch
text/x-patch
Filename: fix-default-handling-for-insert-select-rule.patch
Type: text/x-patch
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/rewrite/rewriteHandler.c | 23 | 2 |
| src/test/regress/expected/updatable_views.out | 19 | 0 |
| src/test/regress/sql/updatable_views.sql | 10 | 0 |
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
new file mode 100644
index c74bac2..5f3f680
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -3861,13 +3861,34 @@ RewriteQuery(Query *parsetree, List *rew
/*
* Each product query has its own copy of the VALUES RTE at the
* same index in the rangetable, so we must finalize each one.
+ *
+ * Note that if the product query is an INSERT ... SELECT, then
+ * the VALUES RTE will be at the same index in the SELECT part of
+ * the product query rather than the top-level product query
+ * itself.
*/
foreach(n, product_queries)
{
Query *pt = (Query *) lfirst(n);
- RangeTblEntry *values_rte = rt_fetch(values_rte_index,
- pt->rtable);
+ RangeTblEntry *values_rte;
+ if (pt->commandType == CMD_INSERT &&
+ list_length(pt->jointree->fromlist) == 1)
+ {
+ RangeTblRef *rtr;
+ RangeTblEntry *selectrte;
+ Query *selectquery;
+
+ rtr = (RangeTblRef *) linitial(pt->jointree->fromlist);
+ selectrte = rt_fetch(rtr->rtindex, pt->rtable);
+ selectquery = selectrte->subquery;
+
+ if (selectquery && IsA(selectquery, Query) &&
+ selectquery->commandType == CMD_SELECT)
+ pt = selectquery;
+ }
+
+ values_rte = rt_fetch(values_rte_index, pt->rtable);
rewriteValuesRTEToNulls(pt, values_rte);
}
}
diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out
new file mode 100644
index 2b578cc..3bc38b6
--- a/src/test/regress/expected/updatable_views.out
+++ b/src/test/regress/expected/updatable_views.out
@@ -3296,6 +3296,25 @@ select * from base_tab_def order by a, c
| View default | | View default |
(22 rows)
+-- Test a DO ALSO INSERT ... SELECT rule
+drop rule base_tab_def_view_ins_rule on base_tab_def_view;
+create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view
+ do also insert into base_tab_def (a, b, e) select new.a, new.b, 'xxx';
+truncate base_tab_def;
+insert into base_tab_def_view values (1, default, default, default, default);
+insert into base_tab_def_view values (2, default, default, default, default),
+ (3, default, default, default, default);
+select * from base_tab_def order by a, e NULLS FIRST;
+ a | b | c | d | e
+---+--------------+---------------+--------------+-----
+ 1 | View default | Table default | View default |
+ 1 | View default | Table default | | xxx
+ 2 | View default | Table default | View default |
+ 2 | View default | Table default | | xxx
+ 3 | View default | Table default | View default |
+ 3 | View default | Table default | | xxx
+(6 rows)
+
drop view base_tab_def_view;
drop table base_tab_def;
-- Test defaults with array assignments
diff --git a/src/test/regress/sql/updatable_views.sql b/src/test/regress/sql/updatable_views.sql
new file mode 100644
index a6aebbc..00810ce
--- a/src/test/regress/sql/updatable_views.sql
+++ b/src/test/regress/sql/updatable_views.sql
@@ -1717,6 +1717,16 @@ insert into base_tab_def_view values (15
insert into base_tab_def_view values (17), (default);
select * from base_tab_def order by a, c NULLS LAST;
+-- Test a DO ALSO INSERT ... SELECT rule
+drop rule base_tab_def_view_ins_rule on base_tab_def_view;
+create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view
+ do also insert into base_tab_def (a, b, e) select new.a, new.b, 'xxx';
+truncate base_tab_def;
+insert into base_tab_def_view values (1, default, default, default, default);
+insert into base_tab_def_view values (2, default, default, default, default),
+ (3, default, default, default, default);
+select * from base_tab_def order by a, e NULLS FIRST;
+
drop view base_tab_def_view;
drop table base_tab_def;