mirror of
https://github.com/postgres/postgres.git
synced 2025-07-22 00:01:40 -04:00
Compare commits
No commits in common. "d8c3ed4f2981821a62fbd83509db28cfa49e8994" and "0e49e23782c55237f54aa60ed7a2b755b47cd4a2" have entirely different histories.
d8c3ed4f29
...
0e49e23782
@ -319,13 +319,9 @@ aminsert (Relation indexRelation,
|
||||
modify any columns covered by the index, but nevertheless requires a
|
||||
new version in the index. The index AM may use this hint to decide
|
||||
to apply bottom-up index deletion in parts of the index where many
|
||||
versions of the same logical row accumulate. Note that updating a non-key
|
||||
column or a column that only appears in a partial index predicate does not
|
||||
affect the value of <literal>indexUnchanged</literal>. The core code
|
||||
determines each tuple's <literal>indexUnchanged</literal> value using a low
|
||||
overhead approach that allows both false positives and false negatives.
|
||||
Index AMs must not treat <literal>indexUnchanged</literal> as an
|
||||
authoritative source of information about tuple visibility or versioning.
|
||||
versions of the same logical row accumulate. Note that updating a
|
||||
non-key column does not affect the value of
|
||||
<literal>indexUnchanged</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -376,7 +376,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
|
||||
an <command>UPDATE</command> that changes the partition key value can
|
||||
cause a row to be moved from a local partition to a foreign-table
|
||||
partition, provided the foreign data wrapper supports tuple routing.
|
||||
However, it is not currently possible to move a row from a
|
||||
However it is not currently possible to move a row from a
|
||||
foreign-table partition to another partition.
|
||||
An <command>UPDATE</command> that would require doing that will fail
|
||||
due to the partitioning constraint, assuming that that is properly
|
||||
|
@ -3947,10 +3947,10 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||
* must be converted, and
|
||||
* - the root partitioned table used for tuple routing.
|
||||
*
|
||||
* If it's a partitioned or inherited table, the root partition or
|
||||
* appendrel RTE doesn't appear elsewhere in the plan and its RT index is
|
||||
* given explicitly in node->rootRelation. Otherwise, the target relation
|
||||
* is the sole relation in the node->resultRelations list.
|
||||
* If it's a partitioned table, the root partition doesn't appear
|
||||
* elsewhere in the plan and its RT index is given explicitly in
|
||||
* node->rootRelation. Otherwise (i.e. table inheritance) the target
|
||||
* relation is the first relation in the node->resultRelations list.
|
||||
*----------
|
||||
*/
|
||||
if (node->rootRelation > 0)
|
||||
@ -3961,7 +3961,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert(list_length(node->resultRelations) == 1);
|
||||
mtstate->rootResultRelInfo = mtstate->resultRelInfo;
|
||||
ExecInitResultRelation(estate, mtstate->resultRelInfo,
|
||||
linitial_int(node->resultRelations));
|
||||
|
@ -1755,9 +1755,6 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
|
||||
parse->resultRelation);
|
||||
int resultRelation = -1;
|
||||
|
||||
/* Pass the root result rel forward to the executor. */
|
||||
rootRelation = parse->resultRelation;
|
||||
|
||||
/* Add only leaf children to ModifyTable. */
|
||||
while ((resultRelation = bms_next_member(root->leaf_result_relids,
|
||||
resultRelation)) >= 0)
|
||||
@ -1881,7 +1878,6 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
|
||||
else
|
||||
{
|
||||
/* Single-relation INSERT/UPDATE/DELETE/MERGE. */
|
||||
rootRelation = 0; /* there's no separate root rel */
|
||||
resultRelations = list_make1_int(parse->resultRelation);
|
||||
if (parse->commandType == CMD_UPDATE)
|
||||
updateColnosLists = list_make1(root->update_colnos);
|
||||
@ -1893,6 +1889,16 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
|
||||
mergeActionLists = list_make1(parse->mergeActionList);
|
||||
}
|
||||
|
||||
/*
|
||||
* If target is a partition root table, we need to mark the
|
||||
* ModifyTable node appropriately for that.
|
||||
*/
|
||||
if (rt_fetch(parse->resultRelation, parse->rtable)->relkind ==
|
||||
RELKIND_PARTITIONED_TABLE)
|
||||
rootRelation = parse->resultRelation;
|
||||
else
|
||||
rootRelation = 0;
|
||||
|
||||
/*
|
||||
* If there was a FOR [KEY] UPDATE/SHARE clause, the LockRows node
|
||||
* will have dealt with fetching non-locked marked rows, else we
|
||||
|
@ -3621,7 +3621,7 @@ create_lockrows_path(PlannerInfo *root, RelOptInfo *rel,
|
||||
* 'operation' is the operation type
|
||||
* 'canSetTag' is true if we set the command tag/es_processed
|
||||
* 'nominalRelation' is the parent RT index for use of EXPLAIN
|
||||
* 'rootRelation' is the partitioned/inherited table root RTI, or 0 if none
|
||||
* 'rootRelation' is the partitioned table root RT index, or 0 if none
|
||||
* 'partColsUpdated' is true if any partitioning columns are being updated,
|
||||
* either from the target relation or a descendent partitioned table.
|
||||
* 'resultRelations' is an integer list of actual RT indexes of target rel(s)
|
||||
|
@ -1895,7 +1895,7 @@ typedef struct ModifyTablePath
|
||||
CmdType operation; /* INSERT, UPDATE, DELETE, or MERGE */
|
||||
bool canSetTag; /* do we set the command tag/es_processed? */
|
||||
Index nominalRelation; /* Parent RT index for use of EXPLAIN */
|
||||
Index rootRelation; /* Root RT index, if partitioned/inherited */
|
||||
Index rootRelation; /* Root RT index, if target is partitioned */
|
||||
bool partColsUpdated; /* some part key in hierarchy updated? */
|
||||
List *resultRelations; /* integer list of RT indexes */
|
||||
List *updateColnosLists; /* per-target-table update_colnos lists */
|
||||
|
@ -205,12 +205,11 @@ typedef struct ProjectSet
|
||||
* Apply rows produced by outer plan to result table(s),
|
||||
* by inserting, updating, or deleting.
|
||||
*
|
||||
* If the originally named target table is a partitioned table or inheritance
|
||||
* tree, both nominalRelation and rootRelation contain the RT index of the
|
||||
* partition root or appendrel RTE, which is not otherwise mentioned in the
|
||||
* plan. Otherwise rootRelation is zero. However, nominalRelation will
|
||||
* always be set, as it's the rel that EXPLAIN should claim is the
|
||||
* INSERT/UPDATE/DELETE/MERGE target.
|
||||
* If the originally named target table is a partitioned table, both
|
||||
* nominalRelation and rootRelation contain the RT index of the partition
|
||||
* root, which is not otherwise mentioned in the plan. Otherwise rootRelation
|
||||
* is zero. However, nominalRelation will always be set, as it's the rel that
|
||||
* EXPLAIN should claim is the INSERT/UPDATE/DELETE/MERGE target.
|
||||
*
|
||||
* Note that rowMarks and epqParam are presumed to be valid for all the
|
||||
* table(s); they can't contain any info that varies across tables.
|
||||
@ -222,7 +221,7 @@ typedef struct ModifyTable
|
||||
CmdType operation; /* INSERT, UPDATE, DELETE, or MERGE */
|
||||
bool canSetTag; /* do we set the command tag/es_processed? */
|
||||
Index nominalRelation; /* Parent RT index for use of EXPLAIN */
|
||||
Index rootRelation; /* Root RT index, if partitioned/inherited */
|
||||
Index rootRelation; /* Root RT index, if target is partitioned */
|
||||
bool partColsUpdated; /* some part key in hierarchy updated? */
|
||||
List *resultRelations; /* integer list of RT indexes */
|
||||
List *updateColnosLists; /* per-target-table update_colnos lists */
|
||||
|
@ -539,33 +539,6 @@ CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a);
|
||||
INSERT INTO z VALUES (NULL, 'text'); -- should fail
|
||||
ERROR: null value in column "aa" of relation "z" violates not-null constraint
|
||||
DETAIL: Failing row contains (null, text).
|
||||
-- Check inherited UPDATE with first child excluded
|
||||
create table some_tab (f1 int, f2 int, f3 int, check (f1 < 10) no inherit);
|
||||
create table some_tab_child () inherits(some_tab);
|
||||
insert into some_tab_child select i, i+1, 0 from generate_series(1,1000) i;
|
||||
create index on some_tab_child(f1, f2);
|
||||
-- while at it, also check that statement-level triggers fire
|
||||
create function some_tab_stmt_trig_func() returns trigger as
|
||||
$$begin raise notice 'updating some_tab'; return NULL; end;$$
|
||||
language plpgsql;
|
||||
create trigger some_tab_stmt_trig
|
||||
before update on some_tab execute function some_tab_stmt_trig_func();
|
||||
explain (costs off)
|
||||
update some_tab set f3 = 11 where f1 = 12 and f2 = 13;
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------------------------------
|
||||
Update on some_tab
|
||||
Update on some_tab_child some_tab_1
|
||||
-> Result
|
||||
-> Index Scan using some_tab_child_f1_f2_idx on some_tab_child some_tab_1
|
||||
Index Cond: ((f1 = 12) AND (f2 = 13))
|
||||
(5 rows)
|
||||
|
||||
update some_tab set f3 = 11 where f1 = 12 and f2 = 13;
|
||||
NOTICE: updating some_tab
|
||||
drop table some_tab cascade;
|
||||
NOTICE: drop cascades to table some_tab_child
|
||||
drop function some_tab_stmt_trig_func();
|
||||
-- Check inherited UPDATE with all children excluded
|
||||
create table some_tab (a int, b int);
|
||||
create table some_tab_child () inherits (some_tab);
|
||||
|
@ -97,25 +97,6 @@ SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid;
|
||||
CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a);
|
||||
INSERT INTO z VALUES (NULL, 'text'); -- should fail
|
||||
|
||||
-- Check inherited UPDATE with first child excluded
|
||||
create table some_tab (f1 int, f2 int, f3 int, check (f1 < 10) no inherit);
|
||||
create table some_tab_child () inherits(some_tab);
|
||||
insert into some_tab_child select i, i+1, 0 from generate_series(1,1000) i;
|
||||
create index on some_tab_child(f1, f2);
|
||||
-- while at it, also check that statement-level triggers fire
|
||||
create function some_tab_stmt_trig_func() returns trigger as
|
||||
$$begin raise notice 'updating some_tab'; return NULL; end;$$
|
||||
language plpgsql;
|
||||
create trigger some_tab_stmt_trig
|
||||
before update on some_tab execute function some_tab_stmt_trig_func();
|
||||
|
||||
explain (costs off)
|
||||
update some_tab set f3 = 11 where f1 = 12 and f2 = 13;
|
||||
update some_tab set f3 = 11 where f1 = 12 and f2 = 13;
|
||||
|
||||
drop table some_tab cascade;
|
||||
drop function some_tab_stmt_trig_func();
|
||||
|
||||
-- Check inherited UPDATE with all children excluded
|
||||
create table some_tab (a int, b int);
|
||||
create table some_tab_child () inherits (some_tab);
|
||||
|
Loading…
x
Reference in New Issue
Block a user