diff --git a/src/gausskernel/runtime/executor/nodeModifyTable.cpp b/src/gausskernel/runtime/executor/nodeModifyTable.cpp index 60a1877cc..edeb04468 100644 --- a/src/gausskernel/runtime/executor/nodeModifyTable.cpp +++ b/src/gausskernel/runtime/executor/nodeModifyTable.cpp @@ -468,7 +468,7 @@ static void RecoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, CmdT * Compute stored updated columns for a tuple */ bool ExecComputeStoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, TupleTableSlot *slot, Tuple tuple, - CmdType cmdtype, ModifyTableState* node, ItemPointer otid, Oid oldPartitionOid, int2 bucketid) + CmdType cmdtype, ItemPointer otid, Oid oldPartitionOid, int2 bucketid) { Relation rel = resultRelInfo->ri_RelationDesc; TupleDesc tupdesc = RelationGetDescr(rel); @@ -485,7 +485,7 @@ bool ExecComputeStoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, T int temp_id = -1; int attnum; uint32 updated_colnum_resno; - Bitmapset* updatedCols = GetUpdatedColumns(node->resultRelInfo, node->ps.state); + Bitmapset* updatedCols = GetUpdatedColumns(resultRelInfo, estate); HeapTuple oldtup = GetTupleForTrigger(estate, NULL, resultRelInfo, oldPartitionOid, bucketid, otid, LockTupleShared, NULL); RecoredUpdateExpr(resultRelInfo, estate, cmdtype); @@ -2174,7 +2174,7 @@ TupleTableSlot* ExecUpdate(ItemPointer tupleid, /* acquire Form_pg_attrdef ad_on_update */ if (result_relation_desc->rd_att->constr && result_relation_desc->rd_att->constr->has_on_update) { - bool update_fix_result = ExecComputeStoredUpdateExpr(result_rel_info, estate, slot, tuple, CMD_UPDATE, node, tupleid, oldPartitionOid, bucketid); + bool update_fix_result = ExecComputeStoredUpdateExpr(result_rel_info, estate, slot, tuple, CMD_UPDATE, tupleid, oldPartitionOid, bucketid); if (!update_fix_result) { tuple = slot->tts_tuple; } diff --git a/src/gausskernel/runtime/opfusion/opfusion_update.cpp b/src/gausskernel/runtime/opfusion/opfusion_update.cpp index 7834ba592..c6c76abf1 100644 --- a/src/gausskernel/runtime/opfusion/opfusion_update.cpp +++ b/src/gausskernel/runtime/opfusion/opfusion_update.cpp @@ -353,6 +353,38 @@ lreplace: } } + /* acquire Form_pg_attrdef ad_on_update */ + if (result_rel_info->ri_RelationDesc->rd_att->constr && + result_rel_info->ri_RelationDesc->rd_att->constr->has_on_update) { + char relkind; + bool isNull = false; + ItemPointer tupleid = NULL; + bool *temp_isnull = NULL; + Datum *temp_values; + relkind = result_rel_info->ri_RelationDesc->rd_rel->relkind; + result_rel_info = result_rel_info + m_c_local.m_estate->result_rel_index; + if (relkind == RELKIND_RELATION || RELKIND_IS_SEQUENCE(relkind)) { + if (result_rel_info->ri_junkFilter != NULL) { + tupleid = (ItemPointer)DatumGetPointer(ExecGetJunkAttribute(m_local.m_reslot, result_rel_info->ri_junkFilter->jf_junkAttNo, &isNull)); + } else { + tupleid = (ItemPointer)&(((HeapTuple)tup)->t_self); + } + } + temp_isnull = m_local.m_reslot->tts_isnull; + m_local.m_reslot->tts_isnull = m_local.m_isnull; + temp_values = m_local.m_reslot->tts_values; + m_local.m_reslot->tts_values = m_local.m_values; + bool update_fix_result = ExecComputeStoredUpdateExpr(result_rel_info, m_c_local.m_estate, m_local.m_reslot, tup, CMD_UPDATE, tupleid, InvalidOid, bucketid); + if (!update_fix_result) { + if (tup != m_local.m_reslot->tts_tuple) { + tableam_tops_free_tuple(tup); + tup = m_local.m_reslot->tts_tuple; + } + } + m_local.m_reslot->tts_isnull = temp_isnull; + m_local.m_reslot->tts_values = temp_values; + } + if (rel->rd_att->constr) { if (!ExecConstraints(result_rel_info, m_local.m_reslot, m_c_local.m_estate)) { if (u_sess->utils_cxt.sql_ignore_strategy_val != SQL_OVERWRITE_NULL) { diff --git a/src/include/executor/node/nodeModifyTable.h b/src/include/executor/node/nodeModifyTable.h index 99098b5e6..7f0bce320 100644 --- a/src/include/executor/node/nodeModifyTable.h +++ b/src/include/executor/node/nodeModifyTable.h @@ -66,4 +66,7 @@ extern void ExecCheckPlanOutput(Relation resultRel, List* targetList); extern void ExecComputeStoredGenerated(ResultRelInfo *resultRelInfo, EState *estate, TupleTableSlot *slot, Tuple oldtuple, CmdType cmdtype); +extern bool ExecComputeStoredUpdateExpr(ResultRelInfo *resultRelInfo, EState *estate, TupleTableSlot *slot, Tuple tuple, + CmdType cmdtype, ItemPointer otid, Oid oldPartitionOid, int2 bucketid); + #endif /* NODEMODIFYTABLE_H */ diff --git a/src/test/regress/expected/single_node_update.out b/src/test/regress/expected/single_node_update.out index 1f8d3563b..076f39f9e 100644 --- a/src/test/regress/expected/single_node_update.out +++ b/src/test/regress/expected/single_node_update.out @@ -560,5 +560,61 @@ alter table t6 modify b timestamp; -- select * from test_feature; -- \! @abs_bindir@/gsql -d mysql -p @portstring@ -c "update test_feature set a=3;" >/dev/null 2>&1; -- select * from test_feature; +CREATE TABLE t_dmpportal_common_intent ( +id bigserial NOT NULL, +intent_name character varying(120) NOT NULL, +upt_time timestamp ON UPDATE CURRENT_TIMESTAMP); +NOTICE: CREATE TABLE will create implicit sequence "t_dmpportal_common_intent_id_seq" for serial column "t_dmpportal_common_intent.id" +ALTER TABLE t_dmpportal_common_intent ADD CONSTRAINT pk_t_dmpportal_common_intent_1675307617_0 PRIMARY KEY USING btree (id); +NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "pk_t_dmpportal_common_intent_1675307617_0" for table "t_dmpportal_common_intent" +insert into t_dmpportal_common_intent values(1,'1', current_timestamp); +insert into t_dmpportal_common_intent values(2,'2', current_timestamp); +insert into t_dmpportal_common_intent values(3,'3', current_timestamp); +select * from t_dmpportal_common_intent; +--?.* +--?.* +--?.* +--?.* +--?.* +(3 rows) + +set enable_opfusion to on; +explain update t_dmpportal_common_intent set intent_name='update_2' where id=2; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------- + [Bypass] + Update on t_dmpportal_common_intent (cost=0.00..8.27 rows=1 width=22) + -> Index Scan using pk_t_dmpportal_common_intent_1675307617_0 on t_dmpportal_common_intent (cost=0.00..8.27 rows=1 width=22) + Index Cond: (id = 2) +(4 rows) + +update t_dmpportal_common_intent set intent_name='update_2' where id=2; +select * from t_dmpportal_common_intent; +--?.* +--?.* +--?.* +--?.* +--?.* +(3 rows) + +set enable_opfusion to off; +update t_dmpportal_common_intent set intent_name='update_2' where id=2; +select * from t_dmpportal_common_intent; +--?.* +--?.* +--?.* +--?.* +--?.* +(3 rows) + +update t_dmpportal_common_intent set intent_name='2' where id=2; +select * from t_dmpportal_common_intent; +--?.* +--?.* +--?.* +--?.* +--?.* +(3 rows) + \c regression DROP database mysql; \ No newline at end of file diff --git a/src/test/regress/sql/single_node_update.sql b/src/test/regress/sql/single_node_update.sql index 969d2f577..8d4be4fca 100644 --- a/src/test/regress/sql/single_node_update.sql +++ b/src/test/regress/sql/single_node_update.sql @@ -233,5 +233,25 @@ alter table t6 modify b timestamp; -- \! @abs_bindir@/gsql -d mysql -p @portstring@ -c "update test_feature set a=3;" >/dev/null 2>&1; -- select * from test_feature; +CREATE TABLE t_dmpportal_common_intent ( +id bigserial NOT NULL, +intent_name character varying(120) NOT NULL, +upt_time timestamp ON UPDATE CURRENT_TIMESTAMP); +ALTER TABLE t_dmpportal_common_intent ADD CONSTRAINT pk_t_dmpportal_common_intent_1675307617_0 PRIMARY KEY USING btree (id); +insert into t_dmpportal_common_intent values(1,'1', current_timestamp); +insert into t_dmpportal_common_intent values(2,'2', current_timestamp); +insert into t_dmpportal_common_intent values(3,'3', current_timestamp); +select * from t_dmpportal_common_intent; +set enable_opfusion to on; +explain update t_dmpportal_common_intent set intent_name='update_2' where id=2; +update t_dmpportal_common_intent set intent_name='update_2' where id=2; +select * from t_dmpportal_common_intent; +set enable_opfusion to off; +update t_dmpportal_common_intent set intent_name='update_2' where id=2; +select * from t_dmpportal_common_intent; + +update t_dmpportal_common_intent set intent_name='2' where id=2; +select * from t_dmpportal_common_intent; + \c regression DROP database mysql; \ No newline at end of file