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 1oDjdl-0000pH-VU for pgsql-hackers@arkaria.postgresql.org; Tue, 19 Jul 2022 09:35:42 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1oDjdk-0007kI-DM for pgsql-hackers@arkaria.postgresql.org; Tue, 19 Jul 2022 09:35:40 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oDjdj-0007il-UA for pgsql-hackers@lists.postgresql.org; Tue, 19 Jul 2022 09:35:40 +0000 Received: from mail.postgrespro.ru ([93.174.131.139]) by makus.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1oDjdg-0001Su-Gx for pgsql-hackers@postgresql.org; Tue, 19 Jul 2022 09:35:38 +0000 Received: from [192.168.28.53] (cyclops.postgrespro.ru [93.174.131.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mail.postgrespro.ru (Postfix) with ESMTPSA id 1BCF821C1CBC; Tue, 19 Jul 2022 12:35:22 +0300 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mail; t=1658223333; bh=aFjTy+qBZ0vreEpL3zgQ+4PLWQM4ZVdDMYxXSscDITw=; h=Date:Subject:To:Cc:References:From:In-Reply-To; b=PY56/FqYJYjwBLEc5wfCyZbhMt3vq5ECveaHWCZErF3N5b56MBzvLDBs5sJWqjOhl SWjBVLGmQ+3oHoD6W3oWq2gEQTd6vxqvSf5rZAWlYZs1LVdP7yxdLhwjRYI1c6aVNs 9C8AuQApVztX3XrHy9m0/Jl2MUW9ONxds1alcym4= Message-ID: <57733596-5fd6-07ec-d65c-67411411f10e@postgrespro.ru> Date: Tue, 19 Jul 2022 14:35:22 +0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Thunderbird/91.11.0 Subject: Re: Fast COPY FROM based on batch insert Content-Language: en-US To: Etsuro Fujita Cc: Justin Pryzby , Zhihong Yu , Amit Langote , tanghy.fnst@fujitsu.com, Ashutosh Bapat , Pg Hackers , Tomas Vondra , houzj.fnst@fujitsu.com References: <20210304203949.GQ29832@telsasoft.com> <20210323032322.GW4203@telsasoft.com> <20210409004956.GN6592@telsasoft.com> <45ad1b94-339b-a841-8885-67ebe6fc5bc1@postgrespro.ru> From: Andrey Lepikhov Organization: Postgres Professional In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 18/7/2022 13:22, Etsuro Fujita wrote: > On Thu, Mar 24, 2022 at 3:43 PM Andrey V. Lepikhov > wrote: >> On 3/22/22 06:54, Etsuro Fujita wrote: >>> * To allow foreign multi insert, the patch made an invasive change to >>> the existing logic to determine whether to use multi insert for the >>> target relation, adding a new member ri_usesMultiInsert to the >>> ResultRelInfo struct, as well as introducing a new function >>> ExecMultiInsertAllowed(). But I’m not sure we really need such a >>> change. Isn’t it reasonable to *adjust* the existing logic to allow >>> foreign multi insert when possible? >> Of course, such approach would look much better, if we implemented it. > >> I'll ponder how to do it. > > I rewrote the decision logic to something much simpler and much less > invasive, which reduces the patch size significantly. Attached is an > updated patch. What do you think about that? > > While working on the patch, I fixed a few issues as well: > > + if (resultRelInfo->ri_FdwRoutine->GetForeignModifyBatchSize != NULL) > + resultRelInfo->ri_BatchSize = > + > resultRelInfo->ri_FdwRoutine->GetForeignModifyBatchSize(resultRelInfo); > > When determining the batch size, I think we should check if the > ExecForeignBatchInsert callback routine is also defined, like other > places such as execPartition.c. For consistency I fixed this by > copying-and-pasting the code from that file. > > + * Also, the COPY command requires a non-zero input list of attributes. > + * Therefore, the length of the attribute list is checked here. > + */ > + if (!cstate->volatile_defexprs && > + list_length(cstate->attnumlist) > 0 && > + !contain_volatile_functions(cstate->whereClause)) > + target_resultRelInfo->ri_usesMultiInsert = > + ExecMultiInsertAllowed(target_resultRelInfo); > > I think “list_length(cstate->attnumlist) > 0” in the if-test would > break COPY FROM; it currently supports multi-inserting into *plain* > tables even in the case where they have no columns, but this would > disable the multi-insertion support in that case. postgres_fdw would > not be able to batch into zero-column foreign tables due to the INSERT > syntax limitation (i.e., the syntax does not allow inserting multiple > empty rows into a zero-column table in a single INSERT statement). > Which is the reason why this was added to the if-test? But I think > some other FDWs might be able to, so I think we should let the FDW > decide whether to allow batching even in that case, when called from > GetForeignModifyBatchSize. So I removed the attnumlist test from the > patch, and modified postgresGetForeignModifyBatchSize as such. I > might miss something, though. Thanks a lot, maybe you forgot this code: /* * If a partition's root parent isn't allowed to use it, neither is the * partition. */ if (rootResultRelInfo->ri_usesMultiInsert) leaf_part_rri->ri_usesMultiInsert = ExecMultiInsertAllowed(leaf_part_rri); Also, maybe to describe in documentation, if the value of batch_size is more than 1, the ExecForeignBatchInsert routine have a chance to be called? -- regards, Andrey Lepikhov Postgres Professional