mirror of https://github.com/citusdata/citus.git
[Bug Fix] : writing incorrect data to target Merge repartition Command (#7659)
We were writing incorrect data to target collection in some cases of merge command. In case of repartition when source query is RELATION. We were referring to incorrect attribute number that was resulting into
this incorrect behavior.
Example :


I have added fixed tests as part of this PR , Thanks.
(cherry picked from commit 5bad6c6a1d
)
pull/7841/head
parent
063cff908e
commit
1893d9a900
|
@ -904,7 +904,7 @@ ConvertRelationRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte,
|
|||
newRangeTableRef->rtindex = SINGLE_RTE_INDEX;
|
||||
sourceResultsQuery->jointree = makeFromExpr(list_make1(newRangeTableRef), NULL);
|
||||
sourceResultsQuery->targetList =
|
||||
CreateAllTargetListForRelation(sourceRte->relid, requiredAttributes);
|
||||
CreateFilteredTargetListForRelation(sourceRte->relid, requiredAttributes);
|
||||
List *restrictionList =
|
||||
GetRestrictInfoListForRelation(sourceRte, plannerRestrictionContext);
|
||||
List *copyRestrictionList = copyObject(restrictionList);
|
||||
|
|
|
@ -45,8 +45,6 @@
|
|||
static RangeTblEntry * AnchorRte(Query *subquery);
|
||||
static List * UnionRelationRestrictionLists(List *firstRelationList,
|
||||
List *secondRelationList);
|
||||
static List * CreateFilteredTargetListForRelation(Oid relationId,
|
||||
List *requiredAttributes);
|
||||
static List * CreateDummyTargetList(Oid relationId, List *requiredAttributes);
|
||||
static TargetEntry * CreateTargetEntryForColumn(Form_pg_attribute attributeTuple, Index
|
||||
rteIndex,
|
||||
|
@ -378,7 +376,7 @@ CreateAllTargetListForRelation(Oid relationId, List *requiredAttributes)
|
|||
* only the required columns of the given relation. If there is not required
|
||||
* columns then a dummy NULL column is put as the only entry.
|
||||
*/
|
||||
static List *
|
||||
List *
|
||||
CreateFilteredTargetListForRelation(Oid relationId, List *requiredAttributes)
|
||||
{
|
||||
Relation relation = relation_open(relationId, AccessShareLock);
|
||||
|
|
|
@ -39,5 +39,7 @@ extern Query * WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation,
|
|||
List *requiredAttributes,
|
||||
RTEPermissionInfo *perminfo);
|
||||
extern List * CreateAllTargetListForRelation(Oid relationId, List *requiredAttributes);
|
||||
extern List * CreateFilteredTargetListForRelation(Oid relationId,
|
||||
List *requiredAttributes);
|
||||
|
||||
#endif /* QUERY_COLOCATION_CHECKER_H */
|
||||
|
|
|
@ -476,6 +476,112 @@ WHEN MATCHED THEN DO NOTHING;
|
|||
Filter: ('2'::bigint = id)
|
||||
(11 rows)
|
||||
|
||||
DROP TABLE IF EXISTS source;
|
||||
DROP TABLE IF EXISTS target;
|
||||
-- Bug Fix Test as part of this PR
|
||||
-- Test 1
|
||||
CREATE TABLE source (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
CREATE TABLE target (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
SELECT create_distributed_table('source', 'id', colocate_with=>'none');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT create_distributed_table('target', 'id', colocate_with=>'none');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO source (id, age, salary) VALUES (1,30, 100000);
|
||||
MERGE INTO ONLY target USING source ON (source.id = target.id)
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (id, salary) VALUES (source.id, source.salary);
|
||||
SELECT * FROM TARGET;
|
||||
id | age | salary
|
||||
---------------------------------------------------------------------
|
||||
1 | | 100000
|
||||
(1 row)
|
||||
|
||||
DROP TABLE IF EXISTS source;
|
||||
DROP TABLE IF EXISTS target;
|
||||
-- Test 2
|
||||
CREATE TABLE source (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
CREATE TABLE target (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
SELECT create_distributed_table('source', 'id', colocate_with=>'none');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT create_distributed_table('target', 'id', colocate_with=>'none');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO source (id, age, salary) VALUES (1,30, 100000);
|
||||
MERGE INTO ONLY target USING source ON (source.id = target.id)
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (salary, id) VALUES (source.salary, source.id);
|
||||
SELECT * FROM TARGET;
|
||||
id | age | salary
|
||||
---------------------------------------------------------------------
|
||||
1 | | 100000
|
||||
(1 row)
|
||||
|
||||
DROP TABLE IF EXISTS source;
|
||||
DROP TABLE IF EXISTS target;
|
||||
-- Test 3
|
||||
CREATE TABLE source (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
CREATE TABLE target (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
SELECT create_distributed_table('source', 'id', colocate_with=>'none');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT create_distributed_table('target', 'id', colocate_with=>'none');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO source (id, age, salary) VALUES (1,30, 100000);
|
||||
MERGE INTO ONLY target USING source ON (source.id = target.id)
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (salary, id, age) VALUES (source.age, source.id, source.salary);
|
||||
SELECT * FROM TARGET;
|
||||
id | age | salary
|
||||
---------------------------------------------------------------------
|
||||
1 | 100000 | 30
|
||||
(1 row)
|
||||
|
||||
DROP TABLE IF EXISTS source;
|
||||
DROP TABLE IF EXISTS target;
|
||||
DROP SCHEMA IF EXISTS merge_vcore_schema CASCADE;
|
||||
|
|
|
@ -312,6 +312,90 @@ WHEN MATCHED THEN DO NOTHING;
|
|||
DROP TABLE IF EXISTS source;
|
||||
DROP TABLE IF EXISTS target;
|
||||
|
||||
|
||||
-- Bug Fix Test as part of this PR
|
||||
-- Test 1
|
||||
CREATE TABLE source (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
|
||||
CREATE TABLE target (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
|
||||
SELECT create_distributed_table('source', 'id', colocate_with=>'none');
|
||||
SELECT create_distributed_table('target', 'id', colocate_with=>'none');
|
||||
|
||||
INSERT INTO source (id, age, salary) VALUES (1,30, 100000);
|
||||
|
||||
MERGE INTO ONLY target USING source ON (source.id = target.id)
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (id, salary) VALUES (source.id, source.salary);
|
||||
|
||||
SELECT * FROM TARGET;
|
||||
DROP TABLE IF EXISTS source;
|
||||
DROP TABLE IF EXISTS target;
|
||||
|
||||
|
||||
-- Test 2
|
||||
CREATE TABLE source (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
|
||||
CREATE TABLE target (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
|
||||
SELECT create_distributed_table('source', 'id', colocate_with=>'none');
|
||||
SELECT create_distributed_table('target', 'id', colocate_with=>'none');
|
||||
|
||||
INSERT INTO source (id, age, salary) VALUES (1,30, 100000);
|
||||
|
||||
MERGE INTO ONLY target USING source ON (source.id = target.id)
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (salary, id) VALUES (source.salary, source.id);
|
||||
|
||||
SELECT * FROM TARGET;
|
||||
DROP TABLE IF EXISTS source;
|
||||
DROP TABLE IF EXISTS target;
|
||||
|
||||
|
||||
-- Test 3
|
||||
CREATE TABLE source (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
|
||||
CREATE TABLE target (
|
||||
id int,
|
||||
age int,
|
||||
salary int
|
||||
);
|
||||
|
||||
SELECT create_distributed_table('source', 'id', colocate_with=>'none');
|
||||
SELECT create_distributed_table('target', 'id', colocate_with=>'none');
|
||||
|
||||
INSERT INTO source (id, age, salary) VALUES (1,30, 100000);
|
||||
|
||||
MERGE INTO ONLY target USING source ON (source.id = target.id)
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (salary, id, age) VALUES (source.age, source.id, source.salary);
|
||||
|
||||
SELECT * FROM TARGET;
|
||||
DROP TABLE IF EXISTS source;
|
||||
DROP TABLE IF EXISTS target;
|
||||
|
||||
|
||||
|
||||
DROP SCHEMA IF EXISTS merge_vcore_schema CASCADE;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue