Skip to content

Commit be8cda2

Browse files
committed
Match PostgreSQL's MERGE NOT MATCHED slot handling
The MERGE NOT MATCHED INSERT path used to build a parent-to-chunk attribute map and allocate a fresh slot for every inserted row, and a flag on the routing state told the standard conversion helper to skip its own work so the slot would not be converted twice. PostgreSQL's ExecMergeNotMatched does none of that. It just calls ExecInsert and lets the routing inside convert the slot when the partition's TupleDesc differs from the parent's. Match that here: drop the manual conversion, drop the flag, and let ts_prepare_tuple_routing convert whenever the chunk's TupleDesc differs from the parent's. The dropped-column helpers in modify_hypertable.c had no other callers and are gone too. The merge regression test already exercises MERGE NOT MATCHED INSERT into a chunk created after a column was dropped from the hypertable.
1 parent 0f5495f commit be8cda2

4 files changed

Lines changed: 2 additions & 69 deletions

File tree

src/chunk_tuple_routing.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ ts_chunk_tuple_routing_create(EState *estate, Hypertable *ht, ResultRelInfo *rri
4545
estate->es_query_cxt,
4646
ts_guc_max_open_chunks_per_insert);
4747

48-
ctr->has_dropped_attrs = false;
49-
5048
return ctr;
5149
}
5250

src/chunk_tuple_routing.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ typedef struct ChunkTupleRouting
2727
SubspaceStore *subspace;
2828
EState *estate;
2929
bool create_compressed_chunk;
30-
bool has_dropped_attrs;
3130

3231
ModifyHypertableState *mht_state; /* state for the ModifyHypertable custom scan node */
3332
ChunkInsertState *cis;

src/nodes/modify_hypertable.c

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <postgres.h>
88
#include <nodes/execnodes.h>
99
#include <nodes/makefuncs.h>
10-
#include <utils/syscache.h>
1110

1211
#include "compat/compat.h"
1312
#include "chunk_tuple_routing.h"
@@ -21,36 +20,6 @@
2120
#include <commands/explain_format.h>
2221
#endif
2322

24-
static AttrNumber
25-
rel_get_natts(Oid relid)
26-
{
27-
HeapTuple tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
28-
29-
if (!HeapTupleIsValid(tp))
30-
elog(ERROR, "cache lookup failed for relation %u", relid);
31-
AttrNumber natts = ((Form_pg_class) GETSTRUCT(tp))->relnatts;
32-
ReleaseSysCache(tp);
33-
return natts;
34-
}
35-
36-
static bool
37-
rel_has_dropped_attrs(Oid relid)
38-
{
39-
AttrNumber natts = rel_get_natts(relid);
40-
for (AttrNumber attno = 1; attno <= natts; attno++)
41-
{
42-
HeapTuple tp = SearchSysCache2(ATTNUM, ObjectIdGetDatum(relid), Int16GetDatum(attno));
43-
if (!HeapTupleIsValid(tp))
44-
continue;
45-
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
46-
bool result = att_tup->attisdropped || att_tup->atthasmissing;
47-
ReleaseSysCache(tp);
48-
if (result)
49-
return true;
50-
}
51-
return false;
52-
}
53-
5423
static bool
5524
should_use_direct_compress(ModifyHypertableState *state)
5625
{
@@ -156,10 +125,6 @@ modify_hypertable_begin(CustomScanState *node, EState *estate, int eflags)
156125
state->ctr->create_compressed_chunk = true;
157126
}
158127

159-
if (mtstate->operation == CMD_MERGE)
160-
state->ctr->has_dropped_attrs =
161-
rel_has_dropped_attrs(state->ctr->hypertable->main_table_relid);
162-
163128
/* setup per tuple exprcontext for tuple routing */
164129
if (!estate->es_per_tuple_exprcontext)
165130
estate->es_per_tuple_exprcontext = CreateExprContext(estate);

src/nodes/modify_hypertable_exec.c

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate,
631631
mtstate->mt_transition_capture->tcs_original_insert_tuple = slot;
632632

633633
/* Convert the tuple to the chunk's rowtype, if necessary */
634-
if (cis->hyper_to_chunk_map != NULL && ctr->has_dropped_attrs == false)
634+
if (cis->hyper_to_chunk_map != NULL)
635635
slot = execute_attr_map_slot(cis->hyper_to_chunk_map->attrMap, slot, cis->slot);
636636

637637
*partRelInfo = cis->result_relation_info;
@@ -3474,36 +3474,7 @@ ExecMergeNotMatched(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
34743474
#else
34753475
context->relaction = action;
34763476
#endif
3477-
if (ctr->has_dropped_attrs)
3478-
{
3479-
AttrMap *map;
3480-
TupleDesc parenttupdesc, chunktupdesc;
3481-
TupleTableSlot *chunk_slot = NULL;
3482-
3483-
parenttupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
3484-
chunktupdesc = RelationGetDescr(ctr->cis->result_relation_info->ri_RelationDesc);
3485-
/* map from parent to chunk */
3486-
#if PG16_LT
3487-
map = build_attrmap_by_name_if_req(parenttupdesc, chunktupdesc);
3488-
#else
3489-
map = build_attrmap_by_name_if_req(parenttupdesc, chunktupdesc, false);
3490-
#endif
3491-
if (map != NULL)
3492-
chunk_slot =
3493-
execute_attr_map_slot(map,
3494-
newslot,
3495-
MakeSingleTupleTableSlot(chunktupdesc,
3496-
&TTSOpsVirtual));
3497-
rslot = ExecInsert(context,
3498-
resultRelInfo,
3499-
ctr,
3500-
(chunk_slot ? chunk_slot : newslot),
3501-
canSetTag);
3502-
if (chunk_slot)
3503-
ExecDropSingleTupleTableSlot(chunk_slot);
3504-
}
3505-
else
3506-
rslot = ExecInsert(context, resultRelInfo, ctr, newslot, canSetTag);
3477+
rslot = ExecInsert(context, resultRelInfo, ctr, newslot, canSetTag);
35073478
mtstate->mt_merge_inserted = 1;
35083479
break;
35093480
case CMD_NOTHING:

0 commit comments

Comments
 (0)