tableam: Inquire slot type from AM, rather than hard-code.
authorAndres Freund <[email protected]>
Wed, 6 Mar 2019 06:32:13 +0000 (22:32 -0800)
committerAndres Freund <[email protected]>
Wed, 6 Mar 2019 06:59:31 +0000 (22:59 -0800)
Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:

22 files changed:
src/backend/access/heap/tuptoaster.c
src/backend/access/index/genam.c
src/backend/access/table/tableam.c
src/backend/catalog/index.c
src/backend/commands/cluster.c
src/backend/commands/tablecmds.c
src/backend/executor/execIndexing.c
src/backend/executor/execMain.c
src/backend/executor/execPartition.c
src/backend/executor/execReplication.c
src/backend/executor/execUtils.c
src/backend/executor/nodeBitmapHeapscan.c
src/backend/executor/nodeIndexonlyscan.c
src/backend/executor/nodeIndexscan.c
src/backend/executor/nodeModifyTable.c
src/backend/executor/nodeSamplescan.c
src/backend/executor/nodeSeqscan.c
src/backend/executor/nodeTidscan.c
src/backend/partitioning/partbounds.c
src/backend/replication/logical/worker.c
src/backend/utils/adt/selfuncs.c
src/tools/pgindent/typedefs.list

index cd921a46005c411e401e3742d4d01e8749b2ed23..7ea964c4936898190c7d209a36d9be1fe829d8eb 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "access/genam.h"
 #include "access/heapam.h"
+#include "access/tableam.h"
 #include "access/tuptoaster.h"
 #include "access/xact.h"
 #include "catalog/catalog.h"
index eafa1fd274a4a213b5ab4a4772eed9c3d21bf97d..1b57e0f85d0739de7aad52b374a76636b00d9457 100644 (file)
@@ -332,8 +332,7 @@ systable_beginscan(Relation heapRelation,
 
    sysscan->heap_rel = heapRelation;
    sysscan->irel = irel;
-   sysscan->slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation),
-                                            &TTSOpsBufferHeapTuple);
+   sysscan->slot = table_gimmegimmeslot(heapRelation, NULL);
 
    if (snapshot == NULL)
    {
@@ -546,8 +545,7 @@ systable_beginscan_ordered(Relation heapRelation,
 
    sysscan->heap_rel = heapRelation;
    sysscan->irel = indexRelation;
-   sysscan->slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation),
-                                            &TTSOpsBufferHeapTuple);
+   sysscan->slot = table_gimmegimmeslot(heapRelation, NULL);
 
    if (snapshot == NULL)
    {
index 1d133d5c7ac363a6b4a896da15e3f9c6801cde98..4e2120409a53064b4c07064971eaa6d43d6f445b 100644 (file)
@@ -23,6 +23,45 @@ char    *default_table_access_method = DEFAULT_TABLE_ACCESS_METHOD;
 bool       synchronize_seqscans = true;
 
 
+const TupleTableSlotOps *
+table_slot_callbacks(Relation relation)
+{
+   const TupleTableSlotOps *tts_cb;
+
+   if (relation->rd_tableam)
+       tts_cb = relation->rd_tableam->slot_callbacks(relation);
+   else
+   {
+       /*
+        * These need to be supported, as some parts of the code (like COPY)
+        * need to create slots for such relations too. It seems better to
+        * centralize the knowledge that a heap slot is the right thing in
+        * that case here.
+        */
+       Assert(relation->rd_rel->relkind == RELKIND_VIEW ||
+              relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
+              relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
+       tts_cb = &TTSOpsHeapTuple;
+   }
+
+   return tts_cb;
+}
+
+TupleTableSlot *
+table_gimmegimmeslot(Relation relation, List **reglist)
+{
+   const TupleTableSlotOps *tts_cb;
+   TupleTableSlot *slot;
+
+   tts_cb = table_slot_callbacks(relation);
+   slot = MakeSingleTupleTableSlot(RelationGetDescr(relation), tts_cb);
+
+   if (reglist)
+       *reglist = lappend(*reglist, slot);
+
+   return slot;
+}
+
 /* ----------------
  *     table_beginscan_parallel - join a parallel scan
  *
index 98fe78f4ce8fc961ee8d8337e2dd0edec8648055..ae68e010980d33c1283d8f617ebca4b10de30ada 100644 (file)
@@ -2504,8 +2504,7 @@ IndexBuildHeapRangeScan(Relation heapRelation,
     */
    estate = CreateExecutorState();
    econtext = GetPerTupleExprContext(estate);
-   slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation),
-                                   &TTSOpsHeapTuple);
+   slot = table_gimmegimmeslot(heapRelation, NULL);
 
    /* Arrange for econtext's scan tuple to be the tuple under test */
    econtext->ecxt_scantuple = slot;
@@ -2871,7 +2870,7 @@ IndexBuildHeapRangeScan(Relation heapRelation,
        MemoryContextReset(econtext->ecxt_per_tuple_memory);
 
        /* Set up for predicate or expression evaluation */
-       ExecStoreHeapTuple(heapTuple, slot, false);
+       ExecStoreBufferHeapTuple(heapTuple, slot, hscan->rs_cbuf);
 
        /*
         * In a partial index, discard tuples that don't satisfy the
@@ -2972,6 +2971,7 @@ IndexCheckExclusion(Relation heapRelation,
 {
    HeapTuple   heapTuple;
    TableScanDesc scan;
+   HeapScanDesc hscan;
    Datum       values[INDEX_MAX_KEYS];
    bool        isnull[INDEX_MAX_KEYS];
    ExprState  *predicate;
@@ -2994,8 +2994,7 @@ IndexCheckExclusion(Relation heapRelation,
     */
    estate = CreateExecutorState();
    econtext = GetPerTupleExprContext(estate);
-   slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation),
-                                   &TTSOpsHeapTuple);
+   slot = table_gimmegimmeslot(heapRelation, NULL);
 
    /* Arrange for econtext's scan tuple to be the tuple under test */
    econtext->ecxt_scantuple = slot;
@@ -3013,6 +3012,7 @@ IndexCheckExclusion(Relation heapRelation,
                                 NULL,  /* scan key */
                                 true,  /* buffer access strategy OK */
                                 true); /* syncscan OK */
+   hscan = (HeapScanDesc) scan;
 
    while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
    {
@@ -3021,7 +3021,7 @@ IndexCheckExclusion(Relation heapRelation,
        MemoryContextReset(econtext->ecxt_per_tuple_memory);
 
        /* Set up for predicate or expression evaluation */
-       ExecStoreHeapTuple(heapTuple, slot, false);
+       ExecStoreBufferHeapTuple(heapTuple, slot, hscan->rs_cbuf);
 
        /*
         * In a partial index, ignore tuples that don't satisfy the predicate.
index 622c2305edfda651cb414a7d1c099606666bfead..95c00f915441b383ba0ca0bf6930db297c36b297 100644 (file)
@@ -940,8 +940,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
        indexScan = NULL;
    }
 
-   slot = MakeSingleTupleTableSlot(RelationGetDescr(OldHeap),
-                                   &TTSOpsBufferHeapTuple);
+   slot = table_gimmegimmeslot(OldHeap, NULL);
    hslot = (BufferHeapTupleTableSlot *) slot;
 
    /* Log what we're doing */
index 54f3ce889e3e9e614d8ad632e97c1d476de0f6bd..81ff6a59eedae51c48abaaae5176f56459d77f80 100644 (file)
@@ -8818,9 +8818,9 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup)
    char       *conbin;
    Expr       *origexpr;
    ExprState  *exprstate;
-   TupleDesc   tupdesc;
    HeapTuple   tuple;
    TableScanDesc scan;
+   HeapScanDesc hscan;
    ExprContext *econtext;
    MemoryContext oldcxt;
    TupleTableSlot *slot;
@@ -8855,12 +8855,12 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup)
    exprstate = ExecPrepareExpr(origexpr, estate);
 
    econtext = GetPerTupleExprContext(estate);
-   tupdesc = RelationGetDescr(rel);
-   slot = MakeSingleTupleTableSlot(tupdesc, &TTSOpsHeapTuple);
+   slot = table_gimmegimmeslot(rel, NULL);
    econtext->ecxt_scantuple = slot;
 
    snapshot = RegisterSnapshot(GetLatestSnapshot());
    scan = table_beginscan(rel, snapshot, 0, NULL);
+   hscan = (HeapScanDesc) scan;
 
    /*
     * Switch to per-tuple memory context and reset it for each tuple
@@ -8870,7 +8870,8 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup)
 
    while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
    {
-       ExecStoreHeapTuple(tuple, slot, false);
+       ExecStoreBufferHeapTuple(tuple, slot, hscan->rs_cbuf);
+
 
        if (!ExecCheck(exprstate, econtext))
            ereport(ERROR,
index 3d8ee38771db3cd38baea8e5bd85c1bb93ab43d2..280a294ec3bb206da9131b151a3db535ba10794a 100644 (file)
 
 #include "access/genam.h"
 #include "access/relscan.h"
+#include "access/tableam.h"
 #include "access/xact.h"
 #include "catalog/index.h"
 #include "executor/executor.h"
@@ -706,8 +707,7 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index,
     * to this slot.  Be sure to save and restore caller's value for
     * scantuple.
     */
-   existing_slot = MakeSingleTupleTableSlot(RelationGetDescr(heap),
-                                            &TTSOpsBufferHeapTuple);
+   existing_slot = table_gimmegimmeslot(heap, NULL);
 
    econtext = GetPerTupleExprContext(estate);
    save_scantuple = econtext->ecxt_scantuple;
index 61be56fe0b72ba7a8f12e6c6bb8f20487057fcbe..eaf35b9e6e18fd02417d0f5f52a2df69ef8d1ec6 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "access/heapam.h"
 #include "access/htup_details.h"
+#include "access/tableam.h"
 #include "access/sysattr.h"
 #include "access/transam.h"
 #include "access/xact.h"
@@ -2802,9 +2803,8 @@ EvalPlanQualSlot(EPQState *epqstate,
        oldcontext = MemoryContextSwitchTo(epqstate->estate->es_query_cxt);
 
        if (relation)
-           *slot = ExecAllocTableSlot(&epqstate->estate->es_tupleTable,
-                                      RelationGetDescr(relation),
-                                      &TTSOpsBufferHeapTuple);
+           *slot = table_gimmegimmeslot(relation,
+                                        &epqstate->estate->es_tupleTable);
        else
            *slot = ExecAllocTableSlot(&epqstate->estate->es_tupleTable,
                                       epqstate->origslot->tts_tupleDescriptor,
index 64437265a4d3c62c6c9d53e9f4796f465f73dffa..6dc591d1a761cea8bfaae3a3b174b047956a5686 100644 (file)
@@ -14,6 +14,7 @@
 #include "postgres.h"
 
 #include "access/table.h"
+#include "access/tableam.h"
 #include "catalog/partition.h"
 #include "catalog/pg_inherits.h"
 #include "catalog/pg_type.h"
@@ -724,9 +725,11 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate,
        {
            TupleConversionMap *map;
            TupleDesc   leaf_desc;
+           const TupleTableSlotOps *tts_cb;
 
            map = leaf_part_rri->ri_PartitionInfo->pi_RootToPartitionMap;
            leaf_desc = RelationGetDescr(leaf_part_rri->ri_RelationDesc);
+           tts_cb = table_slot_callbacks(leaf_part_rri->ri_RelationDesc);
 
            Assert(node->onConflictSet != NIL);
            Assert(rootResultRelInfo->ri_onConflict != NULL);
@@ -740,7 +743,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate,
            leaf_part_rri->ri_onConflict->oc_Existing =
                ExecInitExtraTupleSlot(mtstate->ps.state,
                                       leaf_desc,
-                                      &TTSOpsBufferHeapTuple);
+                                      tts_cb);
 
            /*
             * If the partition's tuple descriptor matches exactly the root
@@ -908,8 +911,7 @@ ExecInitRoutingInfo(ModifyTableState *mtstate,
         * end of the command.
         */
        partrouteinfo->pi_PartitionTupleSlot =
-           ExecInitExtraTupleSlot(estate, RelationGetDescr(partrel),
-                                  &TTSOpsHeapTuple);
+           table_gimmegimmeslot(partrel, &estate->es_tupleTable);
    }
    else
        partrouteinfo->pi_PartitionTupleSlot = NULL;
index 12459b90befedc2828441293ca13224f14660f4c..275b927cb3319701226c738913d881047faed8bc 100644 (file)
@@ -459,11 +459,9 @@ ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate,
    ResultRelInfo *resultRelInfo = estate->es_result_relation_info;
    Relation    rel = resultRelInfo->ri_RelationDesc;
    HeapTupleTableSlot *hsearchslot = (HeapTupleTableSlot *)searchslot;
-   HeapTupleTableSlot *hslot = (HeapTupleTableSlot *)slot;
 
-   /* We expect both searchslot and the slot to contain a heap tuple. */
+   /* We expect the searchslot to contain a heap tuple. */
    Assert(TTS_IS_HEAPTUPLE(searchslot) || TTS_IS_BUFFERTUPLE(searchslot));
-   Assert(TTS_IS_HEAPTUPLE(slot) || TTS_IS_BUFFERTUPLE(slot));
 
    /* For now we support only tables. */
    Assert(rel->rd_rel->relkind == RELKIND_RELATION);
@@ -494,11 +492,11 @@ ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate,
        tuple = ExecFetchSlotHeapTuple(slot, true, NULL);
 
        /* OK, update the tuple and index entries for it */
-       simple_heap_update(rel, &hsearchslot->tuple->t_self, hslot->tuple);
-       ItemPointerCopy(&hslot->tuple->t_self, &slot->tts_tid);
+       simple_heap_update(rel, &hsearchslot->tuple->t_self, tuple);
+       ItemPointerCopy(&tuple->t_self, &slot->tts_tid);
 
        if (resultRelInfo->ri_NumIndices > 0 &&
-           !HeapTupleIsHeapOnly(hslot->tuple))
+           !HeapTupleIsHeapOnly(tuple))
            recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self),
                                                   estate, false, NULL,
                                                   NIL);
index 8e9214833d894754f239308aad5d9a3df6bf8340..7f33fe933b1338346d16233487dd0b53e158c551 100644 (file)
@@ -48,6 +48,7 @@
 #include "access/parallel.h"
 #include "access/relscan.h"
 #include "access/table.h"
+#include "access/tableam.h"
 #include "access/transam.h"
 #include "executor/executor.h"
 #include "jit/jit.h"
@@ -1113,7 +1114,7 @@ ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo)
        relInfo->ri_TrigOldSlot =
            ExecInitExtraTupleSlot(estate,
                                   RelationGetDescr(rel),
-                                  &TTSOpsBufferHeapTuple);
+                                  table_slot_callbacks(rel));
 
        MemoryContextSwitchTo(oldcontext);
    }
@@ -1135,7 +1136,7 @@ ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo)
        relInfo->ri_TrigNewSlot =
            ExecInitExtraTupleSlot(estate,
                                   RelationGetDescr(rel),
-                                  &TTSOpsBufferHeapTuple);
+                                  table_slot_callbacks(rel));
 
        MemoryContextSwitchTo(oldcontext);
    }
@@ -1157,7 +1158,7 @@ ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo)
        relInfo->ri_ReturningSlot =
            ExecInitExtraTupleSlot(estate,
                                   RelationGetDescr(rel),
-                                  &TTSOpsBufferHeapTuple);
+                                  table_slot_callbacks(rel));
 
        MemoryContextSwitchTo(oldcontext);
    }
index 138e79b2046ae3acf840ac1ae07179127eca7769..759edb88b1355621c1daa9b2705f0950b68c34b4 100644 (file)
@@ -917,8 +917,7 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
     */
    ExecInitScanTupleSlot(estate, &scanstate->ss,
                          RelationGetDescr(currentRelation),
-                         &TTSOpsBufferHeapTuple);
-
+                         table_slot_callbacks(currentRelation));
 
    /*
     * Initialize result type and projection.
index 293d48b4ba65afb11ed4c4ce289eaf3bd9d43295..2d954b722a7ded1487c1e0e51f3be0151472ecd7 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "access/genam.h"
 #include "access/relscan.h"
+#include "access/tableam.h"
 #include "access/tupdesc.h"
 #include "access/visibilitymap.h"
 #include "executor/execdebug.h"
@@ -527,7 +528,7 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
     */
    tupDesc = ExecTypeFromTL(node->indextlist);
    ExecInitScanTupleSlot(estate, &indexstate->ss, tupDesc,
-                         &TTSOpsBufferHeapTuple);
+                         table_slot_callbacks(currentRelation));
 
    /*
     * Initialize result type and projection info.  The node's targetlist will
index b52f0ac1f46aa434efbf9e605e9f000e009bea48..82e2829207af0b25573508f803be1359bb95538a 100644 (file)
@@ -932,7 +932,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
     */
    ExecInitScanTupleSlot(estate, &indexstate->ss,
                          RelationGetDescr(currentRelation),
-                         &TTSOpsBufferHeapTuple);
+                         table_slot_callbacks(currentRelation));
 
    /*
     * Initialize result type and projection.
index 14f46612142c7adc14cf4209f3b6c695b5b53e7f..0e52a0c5a5a711e081b16279737b41d44aed4e4e 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "access/heapam.h"
 #include "access/htup_details.h"
+#include "access/tableam.h"
 #include "access/xact.h"
 #include "catalog/catalog.h"
 #include "commands/trigger.h"
@@ -2143,7 +2144,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
        mtstate->mt_plans[i] = ExecInitNode(subplan, estate, eflags);
        mtstate->mt_scans[i] =
            ExecInitExtraTupleSlot(mtstate->ps.state, ExecGetResultType(mtstate->mt_plans[i]),
-                                  &TTSOpsHeapTuple);
+                                  table_slot_callbacks(resultRelInfo->ri_RelationDesc));
 
        /* Also let FDWs init themselves for foreign-table result rels */
        if (!resultRelInfo->ri_usesFdwDirectModify &&
@@ -2203,8 +2204,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
    if (update_tuple_routing_needed)
    {
        ExecSetupChildParentMapForSubplan(mtstate);
-       mtstate->mt_root_tuple_slot = MakeTupleTableSlot(RelationGetDescr(rel),
-                                                        &TTSOpsHeapTuple);
+       mtstate->mt_root_tuple_slot = table_gimmegimmeslot(rel, NULL);
    }
 
    /*
@@ -2297,6 +2297,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
        ExprContext *econtext;
        TupleDesc   relationDesc;
        TupleDesc   tupDesc;
+       const TupleTableSlotOps *tts_cb;
 
        /* insert may only have one plan, inheritance is not expanded */
        Assert(nplans == 1);
@@ -2307,6 +2308,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
 
        econtext = mtstate->ps.ps_ExprContext;
        relationDesc = resultRelInfo->ri_RelationDesc->rd_att;
+       tts_cb = table_slot_callbacks(resultRelInfo->ri_RelationDesc);
 
        /* carried forward solely for the benefit of explain */
        mtstate->mt_excludedtlist = node->exclRelTlist;
@@ -2317,7 +2319,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
        /* initialize slot for the existing tuple */
        resultRelInfo->ri_onConflict->oc_Existing =
            ExecInitExtraTupleSlot(mtstate->ps.state, relationDesc,
-                                  &TTSOpsBufferHeapTuple);
+                                  tts_cb);
 
        /* create the tuple slot for the UPDATE SET projection */
        tupDesc = ExecTypeFromTL((List *) node->onConflictSet);
@@ -2426,15 +2428,18 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
            for (i = 0; i < nplans; i++)
            {
                JunkFilter *j;
+               TupleTableSlot *junkresslot;
 
                subplan = mtstate->mt_plans[i]->plan;
                if (operation == CMD_INSERT || operation == CMD_UPDATE)
                    ExecCheckPlanOutput(resultRelInfo->ri_RelationDesc,
                                        subplan->targetlist);
 
+               junkresslot =
+                   ExecInitExtraTupleSlot(estate, NULL,
+                                          table_slot_callbacks(resultRelInfo->ri_RelationDesc));
                j = ExecInitJunkFilter(subplan->targetlist,
-                                      ExecInitExtraTupleSlot(estate, NULL,
-                                                             &TTSOpsHeapTuple));
+                                      junkresslot);
 
                if (operation == CMD_UPDATE || operation == CMD_DELETE)
                {
index 825fc2e257e47570ce6b579c37274234572fd8d2..b311eb72ff31e4234456300a05cdd8fdc98b931b 100644 (file)
@@ -150,7 +150,7 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags)
    /* and create slot with appropriate rowtype */
    ExecInitScanTupleSlot(estate, &scanstate->ss,
                          RelationGetDescr(scanstate->ss.ss_currentRelation),
-                         &TTSOpsBufferHeapTuple);
+                         table_slot_callbacks(scanstate->ss.ss_currentRelation));
 
    /*
     * Initialize result type and projection.
index 5fd813d89405eee4332efd59aa12e2129b348cbe..2272f93b09d10506ccd0662f0c26771e6de5a482 100644 (file)
@@ -178,7 +178,7 @@ ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
    /* and create slot with the appropriate rowtype */
    ExecInitScanTupleSlot(estate, &scanstate->ss,
                          RelationGetDescr(scanstate->ss.ss_currentRelation),
-                         &TTSOpsBufferHeapTuple);
+                         table_slot_callbacks(scanstate->ss.ss_currentRelation));
 
    /*
     * Initialize result type and projection.
index 9a877874b7587b51cabd767df24c34436c6e2bbc..08872ef9b4f76f5c6ad43ed2f19b64fbed0db278 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "access/heapam.h"
 #include "access/sysattr.h"
+#include "access/tableam.h"
 #include "catalog/pg_type.h"
 #include "executor/execdebug.h"
 #include "executor/nodeTidscan.h"
@@ -538,7 +539,7 @@ ExecInitTidScan(TidScan *node, EState *estate, int eflags)
     */
    ExecInitScanTupleSlot(estate, &tidstate->ss,
                          RelationGetDescr(currentRelation),
-                         &TTSOpsBufferHeapTuple);
+                         table_slot_callbacks(currentRelation));
 
    /*
     * Initialize result type and projection.
index 9a6e421bd1de4c4f234fd74f75f587e41923c1ad..5d9e4dc17165065fdcf025a509e9fb6a38729456 100644 (file)
@@ -1206,9 +1206,9 @@ check_default_partition_contents(Relation parent, Relation default_rel,
        HeapTuple   tuple;
        ExprState  *partqualstate = NULL;
        Snapshot    snapshot;
-       TupleDesc   tupdesc;
        ExprContext *econtext;
        TableScanDesc scan;
+       HeapScanDesc hscan;
        MemoryContext oldCxt;
        TupleTableSlot *tupslot;
 
@@ -1255,7 +1255,6 @@ check_default_partition_contents(Relation parent, Relation default_rel,
            continue;
        }
 
-       tupdesc = CreateTupleDescCopy(RelationGetDescr(part_rel));
        constr = linitial(def_part_constraints);
        partition_constraint = (Expr *)
            map_partition_varattnos((List *) constr,
@@ -1267,8 +1266,9 @@ check_default_partition_contents(Relation parent, Relation default_rel,
 
        econtext = GetPerTupleExprContext(estate);
        snapshot = RegisterSnapshot(GetLatestSnapshot());
-       tupslot = MakeSingleTupleTableSlot(tupdesc, &TTSOpsHeapTuple);
+       tupslot = table_gimmegimmeslot(part_rel, &estate->es_tupleTable);
        scan = table_beginscan(part_rel, snapshot, 0, NULL);
+       hscan = (HeapScanDesc) scan;
 
        /*
         * Switch to per-tuple memory context and reset it for each tuple
@@ -1278,7 +1278,7 @@ check_default_partition_contents(Relation parent, Relation default_rel,
 
        while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
        {
-           ExecStoreHeapTuple(tuple, tupslot, false);
+           ExecStoreBufferHeapTuple(tuple, tupslot, hscan->rs_cbuf);
            econtext->ecxt_scantuple = tupslot;
 
            if (!ExecCheck(partqualstate, econtext))
index e96fb2666b45654911dab544c024169681749411..8f1b83bd0d37f8928ee9a2f5ef6483056591e128 100644 (file)
@@ -24,6 +24,7 @@
 #include "postgres.h"
 
 #include "access/table.h"
+#include "access/tableam.h"
 #include "access/xact.h"
 #include "access/xlog_internal.h"
 #include "catalog/catalog.h"
@@ -698,10 +699,8 @@ apply_handle_update(StringInfo s)
    estate = create_estate_for_relation(rel);
    remoteslot = ExecInitExtraTupleSlot(estate,
                                        RelationGetDescr(rel->localrel),
-                                       &TTSOpsHeapTuple);
-   localslot = ExecInitExtraTupleSlot(estate,
-                                      RelationGetDescr(rel->localrel),
-                                      &TTSOpsBufferHeapTuple);
+                                       &TTSOpsVirtual);
+   localslot = table_gimmegimmeslot(rel->localrel, &estate->es_tupleTable);
    EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1);
 
    PushActiveSnapshot(GetTransactionSnapshot());
@@ -819,9 +818,7 @@ apply_handle_delete(StringInfo s)
    remoteslot = ExecInitExtraTupleSlot(estate,
                                        RelationGetDescr(rel->localrel),
                                        &TTSOpsVirtual);
-   localslot = ExecInitExtraTupleSlot(estate,
-                                      RelationGetDescr(rel->localrel),
-                                      &TTSOpsBufferHeapTuple);
+   localslot = table_gimmegimmeslot(rel->localrel, &estate->es_tupleTable);
    EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1);
 
    PushActiveSnapshot(GetTransactionSnapshot());
index 2fe6634b964b64d021515784a34bc93eb98b8df1..9be46ebc6b3ffbd486332d71ad799bf6079bfaf3 100644 (file)
@@ -5122,8 +5122,7 @@ get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata,
            indexInfo = BuildIndexInfo(indexRel);
 
            /* some other stuff */
-           slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRel),
-                                           &TTSOpsBufferHeapTuple);
+           slot = table_gimmegimmeslot(heapRel, NULL);
            econtext->ecxt_scantuple = slot;
            get_typlenbyval(vardata->atttype, &typLen, &typByVal);
            InitNonVacuumableSnapshot(SnapshotNonVacuumable, RecentGlobalXmin);
index 6bc4a1cdccca11d545f77a1d63eed13c46d35669..b821df9e7125d157680b8b81a9d4793c0d004dd9 100644 (file)
@@ -2416,6 +2416,7 @@ TupleHashIterator
 TupleHashTable
 TupleQueueReader
 TupleTableSlot
+TupleTableSlotOps
 TuplesortInstrumentation
 TuplesortMethod
 TuplesortSpaceType