From e777510f323c09839a6dd9253a327f5dd4172a8b Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Tue, 8 Dec 2020 12:14:22 +0530 Subject: [PATCH v1] 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 | 57 ++++++++++++++++++++------------- src/backend/commands/matview.c | 43 ++++++++++++++----------- 2 files changed, 59 insertions(+), 41 deletions(-) diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 6bf6c5a310..4580cbae1d 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 */ @@ -523,22 +521,28 @@ 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, + 1000, /* To change it to a macro */ + 65535); /* To change it to a macro */ + } 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. @@ -566,11 +570,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 */ @@ -585,12 +585,23 @@ 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; + + /* + * Do not let clearing buffered slots while flushing as they will be + * anyways dropped by table_insert_end. + */ + myState->istate->mistate->clear_slots = false; + + 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 cfc63915f3..610c7ede78 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,13 @@ 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, + 1000, /* To change it to a macro */ + 65535); /* To change it to a macro */ /* * Valid smgr_targblock implies something already wrote to the relation. @@ -494,12 +494,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 +508,26 @@ 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; + + /* + * Do not let clearing buffered slots while flushing as they will be + * anyways dropped by table_insert_end. + */ + myState->istate->mistate->clear_slots = false; + + 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