From d9de92281d7b5c44a6a15994a9a11052149c9981 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Wed, 10 Mar 2021 09:54:59 +0530 Subject: [PATCH v6 2/3] CTAS and REFRESH Mat View With New Multi Insert Table AM This patch adds new multi insert table access methods to CREATE TABLE AS, CREATE MATERIALIZED VIEW and REFRESH MATERIALIZED VIEW. --- src/backend/commands/createas.c | 49 +++++++++++++++++---------------- src/backend/commands/matview.c | 35 ++++++++++++----------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index dce882012e..36ad0ef698 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -58,9 +58,7 @@ typedef struct /* These fields are filled by intorel_startup: */ Relation rel; /* relation to write to */ ObjectAddress reladdr; /* address of rel, for ExecCreateTableAs */ - CommandId output_cid; /* cmin to insert in output tuples */ - int ti_options; /* table_tuple_insert performance options */ - BulkInsertState bistate; /* bulk insert state */ + TableInsertState *istate; /* insert state */ } DR_intorel; /* utility functions for CTAS definition creation */ @@ -546,22 +544,26 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) if (is_matview && !into->skipData) SetMatViewPopulatedState(intoRelationDesc, true); - /* - * Fill private fields of myState for use by later routines - */ - myState->rel = intoRelationDesc; - myState->reladdr = intoRelationAddr; - myState->output_cid = GetCurrentCommandId(true); - myState->ti_options = TABLE_INSERT_SKIP_FSM; - /* * If WITH NO DATA is specified, there is no need to set up the state for - * bulk inserts as there are no tuples to insert. + * bulk inserts and multi inserts as there are no tuples to insert. */ if (!into->skipData) - myState->bistate = GetBulkInsertState(); + { + myState->istate = table_insert_begin(intoRelationDesc, + GetCurrentCommandId(true), + TABLE_INSERT_SKIP_FSM, + true, + true); + } else - myState->bistate = NULL; + myState->istate = NULL; + + /* + * Fill private fields of myState for use by later routines + */ + myState->rel = intoRelationDesc; + myState->reladdr = intoRelationAddr; /* * Valid smgr_targblock implies something already wrote to the relation. @@ -589,11 +591,7 @@ intorel_receive(TupleTableSlot *slot, DestReceiver *self) * would not be cheap either. This also doesn't allow accessing per-AM * data (say a tuple's xmin), but since we don't do that here... */ - table_tuple_insert(myState->rel, - slot, - myState->output_cid, - myState->ti_options, - myState->bistate); + table_multi_insert_v2(myState->istate, slot); } /* We know this is a newly created relation, so there are no indexes */ @@ -608,12 +606,17 @@ static void intorel_shutdown(DestReceiver *self) { DR_intorel *myState = (DR_intorel *) self; - IntoClause *into = myState->into; + int ti_options; - if (!into->skipData) + if (!myState->into->skipData) { - FreeBulkInsertState(myState->bistate); - table_finish_bulk_insert(myState->rel, myState->ti_options); + ti_options = myState->istate->options; + + table_multi_insert_flush(myState->istate); + + table_insert_end(myState->istate); + + table_finish_bulk_insert(myState->rel, ti_options); } /* close rel, but keep lock until commit */ diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index c5c25ce11d..9c6b5f8525 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -52,10 +52,7 @@ typedef struct DestReceiver pub; /* publicly-known function pointers */ Oid transientoid; /* OID of new heap into which to store */ /* These fields are filled by transientrel_startup: */ - Relation transientrel; /* relation to write to */ - CommandId output_cid; /* cmin to insert in output tuples */ - int ti_options; /* table_tuple_insert performance options */ - BulkInsertState bistate; /* bulk insert state */ + TableInsertState *istate; /* insert state */ } DR_transientrel; static int matview_maintenance_depth = 0; @@ -466,10 +463,11 @@ transientrel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) /* * Fill private fields of myState for use by later routines */ - myState->transientrel = transientrel; - myState->output_cid = GetCurrentCommandId(true); - myState->ti_options = TABLE_INSERT_SKIP_FSM | TABLE_INSERT_FROZEN; - myState->bistate = GetBulkInsertState(); + myState->istate = table_insert_begin(transientrel, + GetCurrentCommandId(true), + TABLE_INSERT_SKIP_FSM | TABLE_INSERT_FROZEN, + true, + true); /* * Valid smgr_targblock implies something already wrote to the relation. @@ -494,12 +492,7 @@ transientrel_receive(TupleTableSlot *slot, DestReceiver *self) * cheap either. This also doesn't allow accessing per-AM data (say a * tuple's xmin), but since we don't do that here... */ - - table_tuple_insert(myState->transientrel, - slot, - myState->output_cid, - myState->ti_options, - myState->bistate); + table_multi_insert_v2(myState->istate, slot); /* We know this is a newly created relation, so there are no indexes */ @@ -513,14 +506,20 @@ static void transientrel_shutdown(DestReceiver *self) { DR_transientrel *myState = (DR_transientrel *) self; + int ti_options; + Relation transientrel; + + ti_options = myState->istate->options; + transientrel = myState->istate->rel; + + table_multi_insert_flush(myState->istate); - FreeBulkInsertState(myState->bistate); + table_insert_end(myState->istate); - table_finish_bulk_insert(myState->transientrel, myState->ti_options); + table_finish_bulk_insert(transientrel, ti_options); /* close transientrel, but keep lock until commit */ - table_close(myState->transientrel, NoLock); - myState->transientrel = NULL; + table_close(transientrel, NoLock); } /* -- 2.25.1