!6581 修复大数据量下replace分配过多内存的问题

Merge pull request !6581 from chenxiaobin/fixReplace
This commit is contained in:
opengauss_bot
2024-10-30 08:26:29 +00:00
committed by Gitee

View File

@ -3349,27 +3349,21 @@ uint64 GetDeleteLimitCount(ExprContext* econtext, PlanState* scan, Limit *limitP
return (uint64)iCount;
}
static TupleTableSlot* ExecReplace(EState* estate, ModifyTableState* node, TupleTableSlot* slot,
TupleTableSlot* plan_slot, int2 bucketid, int hi_options, List* partition_list, char* partExprKeyStr,
bool replaceNull)
/* REPLACE INTO not support sequence, check columns to report ERROR */
static void checkSequenceForReplace(Relation rel)
{
Form_pg_attribute att_tup;
Oid seqOid = InvalidOid;
Relation rel = estate->es_result_relation_info->ri_RelationDesc;
TupleTableSlot* (*ExecInsert)(
ModifyTableState* state, TupleTableSlot*, TupleTableSlot*, EState*, bool, int, List**, char*, bool) = NULL;
static int tableNameSize = NAMEDATALEN * 2 + 2;
char tableName[tableNameSize] = {0};
ExecInsert = ExecInsertT<false>;
/* REPLACE INTO not support sequence, check columns to report ERROR */
for (int attrno=1; attrno<=rel->rd_att->natts; ++attrno) {
for (int attrno = 1; attrno <= rel->rd_att->natts; ++attrno) {
att_tup = &rel->rd_att->attrs[attrno-1];
errno_t rc;
char *nspname = get_namespace_name(rel->rd_rel->relnamespace);
char tableName[NAMEDATALEN*2+2] = {0};
text *tbname;
text *attname;
rc = memset_s(tableName, NAMEDATALEN*2, 0, NAMEDATALEN*2);
rc = memset_s(tableName, tableNameSize, 0, tableNameSize);
securec_check(rc, "\0", "\0");
if (nspname != NULL) {
@ -3377,13 +3371,13 @@ static TupleTableSlot* ExecReplace(EState* estate, ModifyTableState* node, Tuple
int nspnameLen = strlen(nspname);
int symLen = strlen(sym);
int tbnameLen = strlen(rel->rd_rel->relname.data);
rc = memcpy_s(&tableName[0], NAMEDATALEN*2+2, nspname, nspnameLen);
securec_check(rc, "\0","\0");
rc = memcpy_s(&tableName[nspnameLen], NAMEDATALEN*2+2, sym, symLen);
securec_check(rc, "\0","\0");
rc = memcpy_s(&tableName[nspnameLen+symLen], NAMEDATALEN*2+2, rel->rd_rel->relname.data, tbnameLen);
securec_check(rc, "\0","\0");
tableName[nspnameLen+symLen+tbnameLen] = 0;
rc = memcpy_s(&tableName[0], tableNameSize, nspname, nspnameLen);
securec_check(rc, "\0", "\0");
rc = memcpy_s(&tableName[nspnameLen], tableNameSize, sym, symLen);
securec_check(rc, "\0", "\0");
rc = memcpy_s(&tableName[nspnameLen + symLen], tableNameSize, rel->rd_rel->relname.data, tbnameLen);
securec_check(rc, "\0", "\0");
tableName[nspnameLen + symLen + tbnameLen] = 0;
tbname = cstring_to_text(&tableName[0]);
} else {
tbname = cstring_to_text(rel->rd_rel->relname.data);
@ -3391,11 +3385,20 @@ static TupleTableSlot* ExecReplace(EState* estate, ModifyTableState* node, Tuple
attname = cstring_to_text(att_tup->attname.data);
seqOid = pg_get_serial_sequence_oid(tbname, attname);
if (OidIsValid(seqOid))
if (OidIsValid(seqOid)) {
elog(ERROR, "REPLACE can not work on sequence!");
}
}
}
static TupleTableSlot* ExecReplace(EState* estate, ModifyTableState* node, TupleTableSlot* slot,
TupleTableSlot* plan_slot, int2 bucketid, int hi_options, List* partition_list, char* partExprKeyStr,
bool replaceNull)
{
TupleTableSlot* (*ExecInsert)(
ModifyTableState* state, TupleTableSlot*, TupleTableSlot*, EState*, bool, int, List**, char*, bool) = NULL;
ExecInsert = ExecInsertT<false>;
/* set flag to start loop */
node->isConflict = true;
@ -3625,6 +3628,11 @@ static TupleTableSlot* ExecModifyTable(PlanState* state)
subPlanState->state->es_skip_early_free = true;
subPlanState->state->es_skip_early_deinit_consumer = true;
if (node->isReplace) {
checkSequenceForReplace(estate->es_result_relation_info->ri_RelationDesc);
}
/*
* Fetch rows from subplan(s), and execute the required table modification
* for each row.