forked from huawei/openGauss-server
fix upsert core and cross-partition upsert
This commit is contained in:
parent
d9dc69168f
commit
4d2c0d708e
|
|
@ -309,6 +309,7 @@ static ModifyTable* _copyModifyTable(const ModifyTable* from)
|
|||
COPY_NODE_FIELD(updateTlist);
|
||||
COPY_NODE_FIELD(exclRelTlist);
|
||||
COPY_SCALAR_FIELD(exclRelRTIndex);
|
||||
COPY_SCALAR_FIELD(partKeyUpsert);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
|
@ -3489,7 +3490,7 @@ static UpsertExpr* _copyUpsertExpr(const UpsertExpr* from)
|
|||
COPY_NODE_FIELD(updateTlist);
|
||||
COPY_NODE_FIELD(exclRelTlist);
|
||||
COPY_SCALAR_FIELD(exclRelIndex);
|
||||
|
||||
COPY_SCALAR_FIELD(partKeyUpsert);
|
||||
return newnode;
|
||||
}
|
||||
static CommonTableExpr* _copyCommonTableExpr(const CommonTableExpr* from)
|
||||
|
|
|
|||
|
|
@ -694,7 +694,7 @@ static bool _equalUpsertExpr(const UpsertExpr* a, const UpsertExpr* b)
|
|||
COMPARE_NODE_FIELD(updateTlist);
|
||||
COMPARE_NODE_FIELD(exclRelTlist);
|
||||
COMPARE_SCALAR_FIELD(exclRelIndex);
|
||||
|
||||
COMPARE_SCALAR_FIELD(partKeyUpsert);
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -757,12 +757,14 @@ static void _outModifyTable(StringInfo str, ModifyTable* node)
|
|||
WRITE_NODE_FIELD(updateTlist);
|
||||
WRITE_NODE_FIELD(exclRelTlist);
|
||||
WRITE_INT_FIELD(exclRelRTIndex);
|
||||
WRITE_BOOL_FIELD(partKeyUpsert);
|
||||
}
|
||||
#else
|
||||
WRITE_ENUM_FIELD(upsertAction, UpsertAction);
|
||||
WRITE_NODE_FIELD(updateTlist);
|
||||
WRITE_NODE_FIELD(exclRelTlist);
|
||||
WRITE_INT_FIELD(exclRelRTIndex);
|
||||
WRITE_BOOL_FIELD(partKeyUpsert);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -782,6 +784,7 @@ static void _outUpsertExpr(StringInfo str, const UpsertExpr* node)
|
|||
WRITE_NODE_FIELD(updateTlist);
|
||||
WRITE_NODE_FIELD(exclRelTlist);
|
||||
WRITE_INT_FIELD(exclRelIndex);
|
||||
WRITE_BOOL_FIELD(partKeyUpsert);
|
||||
}
|
||||
static void _outMergeWhenClause(StringInfo str, const MergeWhenClause* node)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3682,7 +3682,7 @@ static ModifyTable* _readModifyTable(ModifyTable* local_node)
|
|||
IF_EXIST(exclRelRTIndex) {
|
||||
READ_INT_FIELD(exclRelRTIndex);
|
||||
}
|
||||
|
||||
READ_BOOL_FIELD(partKeyUpsert);
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
|
|
@ -3694,7 +3694,7 @@ static UpsertExpr* _readUpsertExpr(void)
|
|||
READ_NODE_FIELD(updateTlist);
|
||||
READ_NODE_FIELD(exclRelTlist);
|
||||
READ_INT_FIELD(exclRelIndex);
|
||||
|
||||
READ_BOOL_FIELD(partKeyUpsert);
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1845,6 +1845,7 @@ static UpsertExpr* transformUpsertClause(ParseState* pstate, UpsertClause* upser
|
|||
List* exclRelTlist = NIL;
|
||||
UpsertAction action = UPSERT_NOTHING;
|
||||
Relation targetrel = pstate->p_target_relation;
|
||||
bool partKeyUpsert = false;
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
if (targetrel->rd_rel->relhastriggers) {
|
||||
|
|
@ -1872,7 +1873,6 @@ static UpsertExpr* transformUpsertClause(ParseState* pstate, UpsertClause* upser
|
|||
* adds have to be reset. markVarForSelectPriv() will add the exact
|
||||
* required permissions back.
|
||||
*/
|
||||
|
||||
exclRelTlist = BuildExcludedTargetlist(targetrel, exclRelIndex);
|
||||
exclRte->requiredPerms = 0;
|
||||
exclRte->selectedCols = NULL;
|
||||
|
|
@ -1886,6 +1886,7 @@ static UpsertExpr* transformUpsertClause(ParseState* pstate, UpsertClause* upser
|
|||
|
||||
updateTlist = transformTargetList(pstate, upsertClause->targetList);
|
||||
updateTlist = transformUpdateTargetList(pstate, updateTlist, upsertClause->targetList, relation);
|
||||
|
||||
/* We can't update primary or unique key in upsert, check it here */
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
if (IS_PGXC_COORDINATOR && !u_sess->attr.attr_sql.enable_upsert_to_merge) {
|
||||
|
|
@ -1894,6 +1895,7 @@ static UpsertExpr* transformUpsertClause(ParseState* pstate, UpsertClause* upser
|
|||
#else
|
||||
checkUpsertTargetlist(pstate->p_target_relation, updateTlist);
|
||||
#endif
|
||||
partKeyUpsert = RELATION_IS_PARTITIONED(targetrel) && targetListHasPartitionKey(updateTlist, targetrel->rd_id);
|
||||
}
|
||||
|
||||
/* Finally, build DUPLICATE KEY UPDATE [NOTHING | ... ] expression */
|
||||
|
|
@ -1902,6 +1904,7 @@ static UpsertExpr* transformUpsertClause(ParseState* pstate, UpsertClause* upser
|
|||
result->exclRelIndex = exclRelIndex;
|
||||
result->exclRelTlist = exclRelTlist;
|
||||
result->upsertAction = action;
|
||||
result->partKeyUpsert = partKeyUpsert;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8760,6 +8760,7 @@ ModifyTable* make_modifytable(CmdType operation, bool canSetTag, List* resultRel
|
|||
node->updateTlist = upsertClause->updateTlist;
|
||||
node->exclRelTlist = upsertClause->exclRelTlist;
|
||||
node->exclRelRTIndex = upsertClause->exclRelIndex;
|
||||
node->partKeyUpsert = upsertClause->partKeyUpsert;
|
||||
} else {
|
||||
node->upsertAction = UPSERT_NONE;
|
||||
node->updateTlist = NIL;
|
||||
|
|
|
|||
|
|
@ -1304,6 +1304,11 @@ bool ExecCheckIndexConstraints(TupleTableSlot* slot, EState* estate,
|
|||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("INSERT ON DUPLICATE KEY UPDATE does not support deferrable"
|
||||
" unique constraints/exclusion constraints.")));
|
||||
|
||||
/*
|
||||
* We consider a partitioned table with a global index as a normal table,
|
||||
* because conflicts can be between multiple partitions.
|
||||
*/
|
||||
if (isPartitioned && !RelationIsGlobalIndex(indexRelation)) {
|
||||
partitionedindexid = RelationGetRelid(indexRelation);
|
||||
if (!PointerIsValid(partitionIndexOidList)) {
|
||||
|
|
|
|||
|
|
@ -533,7 +533,7 @@ checktest:
|
|||
|
||||
*returning = ExecUpdate(conflictTid, oldPartitionOid, bucketid, NULL,
|
||||
upsertState->us_updateproj, planSlot, &mtstate->mt_epqstate,
|
||||
mtstate, canSetTag, false);
|
||||
mtstate, canSetTag, ((ModifyTable*)mtstate->ps.plan)->partKeyUpsert);
|
||||
ReleaseBuffer(buffer);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -432,6 +432,7 @@ typedef struct ModifyTable {
|
|||
List* updateTlist; /* List of UPDATE target */
|
||||
List* exclRelTlist; /* target list of the EXECLUDED pseudo relation */
|
||||
Index exclRelRTIndex; /* RTI of the EXCLUDED pseudo relation */
|
||||
bool partKeyUpsert;
|
||||
|
||||
OpMemInfo mem_info; /* Memory info for modify node */
|
||||
} ModifyTable;
|
||||
|
|
|
|||
|
|
@ -1398,6 +1398,7 @@ typedef struct UpsertExpr {
|
|||
List* updateTlist; /* List of UPDATE TargetEntrys */
|
||||
List* exclRelTlist; /* tlist of the 'EXCLUDED' pseudo relation */
|
||||
int exclRelIndex; /* RT index of 'EXCLUDED' relation */
|
||||
bool partKeyUpsert; /* we allow upsert index key and partition key in B_FORMAT */
|
||||
} UpsertExpr;
|
||||
|
||||
#endif /* PRIMNODES_H */
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ create table pkt (a int primary key, b int, c int);
|
|||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pkt_pkey" for table "pkt"
|
||||
create table fkt (a int primary key, b int references pkt, c int);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "fkt_pkey" for table "fkt"
|
||||
create table up_neg_11(c1 int, c2 int) partition by range(c1)(partition p1 values less than(10), partition p2 values less than(maxvalue));
|
||||
create unique index index_up_neg_11 on up_neg_11(c2);
|
||||
-- procedure test
|
||||
CREATE SCHEMA upsert_test_procedure;
|
||||
-- explain test
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ insert into up_neg_07 select a,a,a from generate_series(1,20) as a;
|
|||
insert into up_neg_08 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_09 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_10 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_11 values(1,1),(2,2),(11,11),(12,12);
|
||||
-- table cases
|
||||
---- col table
|
||||
insert into up_neg_01 values(1,2,3) on duplicate key update c3 = 1;
|
||||
|
|
@ -120,6 +121,22 @@ insert into up_neg_09 values(101, 1, 1) on duplicate key update c2=101;
|
|||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c2 =1,c3=101;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
---- cross-partition upsert
|
||||
insert into up_neg_11 values(1, 1) on duplicate key update c1 = 15;
|
||||
select * from up_neg_11 partition(p1);
|
||||
c1 | c2
|
||||
----+----
|
||||
2 | 2
|
||||
(1 row)
|
||||
|
||||
select * from up_neg_11 partition(p2);
|
||||
c1 | c2
|
||||
----+----
|
||||
11 | 11
|
||||
12 | 12
|
||||
15 | 1
|
||||
(3 rows)
|
||||
|
||||
--update unique key mul type plans
|
||||
EXPLAIN (VERBOSE on, COSTS off) insert into up_neg_10 values(101, 1, 300) on duplicate key update c1=101;
|
||||
QUERY PLAN
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ create view up_view as select *from up_neg_01;
|
|||
create materialized view mat_view as select *from up_neg_01;
|
||||
create table pkt (a int primary key, b int, c int);
|
||||
create table fkt (a int primary key, b int references pkt, c int);
|
||||
create table up_neg_11(c1 int, c2 int) partition by range(c1)(partition p1 values less than(10), partition p2 values less than(maxvalue));
|
||||
create unique index index_up_neg_11 on up_neg_11(c2);
|
||||
|
||||
|
||||
-- procedure test
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ insert into up_neg_07 select a,a,a from generate_series(1,20) as a;
|
|||
insert into up_neg_08 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_09 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_10 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_11 values(1,1),(2,2),(11,11),(12,12);
|
||||
|
||||
-- table cases
|
||||
---- col table
|
||||
|
|
@ -98,6 +99,11 @@ insert into up_neg_09 values(101, 1, 1) on duplicate key update c3=101;
|
|||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c2=101;
|
||||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c2 =1,c3=101;
|
||||
|
||||
---- cross-partition upsert
|
||||
insert into up_neg_11 values(1, 1) on duplicate key update c1 = 15;
|
||||
select * from up_neg_11 partition(p1);
|
||||
select * from up_neg_11 partition(p2);
|
||||
|
||||
--update unique key mul type plans
|
||||
EXPLAIN (VERBOSE on, COSTS off) insert into up_neg_10 values(101, 1, 300) on duplicate key update c1=101;
|
||||
insert into up_neg_10 values(101, 1, 300) on duplicate key update c3=101;
|
||||
|
|
|
|||
Loading…
Reference in New Issue