Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jXoM2-0002ID-L1 for pgsql-hackers@arkaria.postgresql.org; Sun, 10 May 2020 15:59:02 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1jXoLU-0007Y9-Nu for pgsql-hackers@arkaria.postgresql.org; Sun, 10 May 2020 15:58:28 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jXoLU-0007Y2-CJ for pgsql-hackers@lists.postgresql.org; Sun, 10 May 2020 15:58:28 +0000 Received: from mail-qk1-x743.google.com ([2607:f8b0:4864:20::743]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1jXoLQ-0001ax-DT for pgsql-hackers@lists.postgresql.org; Sun, 10 May 2020 15:58:27 +0000 Received: by mail-qk1-x743.google.com with SMTP id g185so7201283qke.7 for ; Sun, 10 May 2020 08:58:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=ugg/NYCo3ijAb5Y7YdUWCGMp7XGlJ4qmK/IAhnubuWE=; b=qX9Uw8JdtulJLw646Og/SZ24QIubR5Je2gHgp+odUVREfzx8VUBOtVljz4XwmB45h/ QPHxKDmK//DM7NdBmFIulL/A3gxQ/JX91tdL0XUeMZnVlPdsne63HWwSWVMwA8jVORFO /0rKDGnrxV8YL3lxigg5iODU/lptLME6eUvycSjHZ/+3C1VUxKcDv1e+4EWyLIF+1OxT dfJ2t5g6TapDkhdMChvmi8ICll/LtzdYIZIeVgtYVo0eEE4tQ6YlGPPQmHbi1GS4SJM9 ViwWlxxm9nmd6OOrJLuElyBTjT93m4Z12RHyLEwEQGzIAcFWGatXoIzD7wareKCoTAy8 gr+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=ugg/NYCo3ijAb5Y7YdUWCGMp7XGlJ4qmK/IAhnubuWE=; b=Ay78takVIuYjbNrvv6apMm7JOffAqGvZ/LaWRB52YYShw2VmJDDR0iMHs4KL52GJyw MzBszCqMvON/Z63l4m78pOcl4F4v3ttYHmsNeLxi7q0fI8YUwzqwVmHbZZOCCsB/fDtp 9vpOey1U3HftVZpg4lp5+Ap9uT5Ho07g6PDgISZlx0hvR5HeUuU9say55Zuu9epMlu66 C/6gz2jw9kSUWqBrByAMgulZhmOzayvL/oQnrqdGYLcG4Us3JoHYLo5ecfSw7r94Gcr4 OIZmoXDcM6ThWKbPrW4Gb3bhJvdP44ia0VLcm60Pbz0hv4GXJRLEt6+9b7lBnUBsdbIk Wj4A== X-Gm-Message-State: AGi0PuYwrzxtFM2QzWFnoyIW17Z9bowReAfsX2Qbr0HLHWc8ByZOP/5m exY0jxKjX+ojkKfFFHvMunF7D5nQj5Y= X-Google-Smtp-Source: APiQypKHpUVFpriQTanAnvoNktk5+qfhkQTdNlGU1WvIJZCBEzKABqGBwv3XzGnUV+dSU39JImjUDA== X-Received: by 2002:a37:a2d4:: with SMTP id l203mr10956916qke.485.1589126301435; Sun, 10 May 2020 08:58:21 -0700 (PDT) Received: from pryzbyj (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id k43sm7296529qtk.67.2020.05.10.08.58.19 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 10 May 2020 08:58:20 -0700 (PDT) Received: by pryzbyj (Postfix, from userid 1000) id 697D7800831; Sun, 10 May 2020 10:58:18 -0500 (CDT) Date: Sun, 10 May 2020 10:58:18 -0500 From: Justin Pryzby To: pgsql-hackers@lists.postgresql.org Subject: Re: should INSERT SELECT use a BulkInsertState? Message-ID: <20200510155818.GA10164@telsasoft.com> References: <20200508072545.GA9701@telsasoft.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="4Ckj6UjgE2iN1+kY" Content-Disposition: inline In-Reply-To: <20200508072545.GA9701@telsasoft.com> User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --4Ckj6UjgE2iN1+kY Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, May 08, 2020 at 02:25:45AM -0500, Justin Pryzby wrote: > Seems to me it should, at least conditionally. At least if there's a function > scan or a relation or .. > > I mentioned a bit about our use-case here: > https://www.postgresql.org/message-id/20200219173742.GA30939%40telsasoft.com > => I'd prefer our loaders to write their own data rather than dirtying large > fractions of buffer cache and leaving it around for other backends to clean up. Nobody suggested otherwise so I added here and cleaned up to pass tests. https://commitfest.postgresql.org/28/2553/ -- Justin --4Ckj6UjgE2iN1+kY Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v1-0001-Make-INSERT-SELECT-use-a-BulkInsertState.patch" From ba5cf05960a097cf82c10a29af81f4f66a9274a6 Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Fri, 8 May 2020 02:17:32 -0500 Subject: [PATCH v1] Make INSERT SELECT use a BulkInsertState --- src/backend/executor/nodeModifyTable.c | 21 +++++++++++++++++++-- src/include/nodes/execnodes.h | 2 ++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 20a4c474cc..aa85245f39 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -578,7 +578,7 @@ ExecInsert(ModifyTableState *mtstate, table_tuple_insert_speculative(resultRelationDesc, slot, estate->es_output_cid, 0, - NULL, + NULL, /* Bulk insert not supported */ specToken); /* insert index entries for tuple */ @@ -617,7 +617,7 @@ ExecInsert(ModifyTableState *mtstate, /* insert the tuple normally */ table_tuple_insert(resultRelationDesc, slot, estate->es_output_cid, - 0, NULL); + 0, mtstate->bistate); /* insert index entries for tuple */ if (resultRelInfo->ri_NumIndices > 0) @@ -2332,6 +2332,17 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) mtstate->mt_arowmarks = (List **) palloc0(sizeof(List *) * nplans); mtstate->mt_nplans = nplans; + mtstate->bistate = NULL; + if (operation == CMD_INSERT && + node->onConflictAction != ONCONFLICT_UPDATE && + node->rootResultRelIndex < 0) + { + Plan *p = linitial(node->plans); + Assert(nplans == 1); + + if (!IsA(p, Result) && !IsA(p, ProjectSet) && !IsA(p, ValuesScan)) + mtstate->bistate = GetBulkInsertState(); + } /* set up epqstate with dummy subplan data for the moment */ EvalPlanQualInit(&mtstate->mt_epqstate, estate, NULL, NIL, node->epqParam); @@ -2776,6 +2787,12 @@ ExecEndModifyTable(ModifyTableState *node) resultRelInfo); } + if (node->bistate) + { + FreeBulkInsertState(node->bistate); + table_finish_bulk_insert((getTargetResultRelInfo(node))->ri_RelationDesc, 0); + } + /* * Close all the partitioned tables, leaf partitions, and their indices * and release the slot used for tuple routing, if set. diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 4fee043bb2..daf365f181 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -14,6 +14,7 @@ #ifndef EXECNODES_H #define EXECNODES_H +#include "access/heapam.h" #include "access/tupconvert.h" #include "executor/instrument.h" #include "fmgr.h" @@ -1177,6 +1178,7 @@ typedef struct ModifyTableState List **mt_arowmarks; /* per-subplan ExecAuxRowMark lists */ EPQState mt_epqstate; /* for evaluating EvalPlanQual rechecks */ bool fireBSTriggers; /* do we need to fire stmt triggers? */ + BulkInsertState bistate; /* State for bulk insert like INSERT SELECT */ /* * Slot for storing tuples in the root partitioned table's rowtype during -- 2.17.0 --4Ckj6UjgE2iN1+kY--