Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rNRxC-00C9rW-78 for pgsql-hackers@arkaria.postgresql.org; Wed, 10 Jan 2024 06:20:43 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1rNRxB-000XCO-2f for pgsql-hackers@arkaria.postgresql.org; Wed, 10 Jan 2024 06:20:41 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rNRx9-000XCF-Vk for pgsql-hackers@lists.postgresql.org; Wed, 10 Jan 2024 06:20:40 +0000 Received: from mail.clear-code.com ([153.126.206.245]) by magus.postgresql.org with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rNRx5-000mU1-GW for pgsql-hackers@postgresql.org; Wed, 10 Jan 2024 06:20:39 +0000 Received: from localhost (unknown [IPv6:2404:7a80:89c1:1200:6af9:2266:1443:f149]) by mail.clear-code.com (Postfix) with ESMTPSA id 868A35F47E4; Wed, 10 Jan 2024 15:20:27 +0900 (JST) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.clear-code.com 868A35F47E4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=clear-code.com; s=default; t=1704867627; bh=uOFEMtRwNoJliVEANmbkHsLJqYVKsvZDfi+cgsxQ7b4=; h=Date:To:Cc:Subject:From:In-Reply-To:References:From; b=ixruREiULL/06x7KV9U/8RRWD2UAf5JZF47QfrepvxQtr+x7k1wmT02A2YEWZ5+wj JsqK+l4KgJoOWztQK3Tyc9HDqx+d8uOQgjytEMwjrbNgeb2a+T0xNiEwmBaFNFafP+ tQT4optIIWpMFlAvmOSuIuUl49oZuPSdg+3WrZkw= Date: Wed, 10 Jan 2024 15:20:23 +0900 (JST) Message-Id: <20240110.152023.1920937326588672387.kou@clear-code.com> To: zhjwpku@gmail.com Cc: sawada.mshk@gmail.com, michael@paquier.xyz, andrew@dunslane.net, nathandbossart@gmail.com, pgsql-hackers@postgresql.org Subject: Re: Make COPY format extendable: Extract COPY TO format implementations From: Sutou Kouhei In-Reply-To: References: <20231221.183504.1240642084042888377.kou@clear-code.com> X-Mailer: Mew version 6.8 on Emacs 29.1 Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Rspamd-Queue-Id: 868A35F47E4 X-Rspamd-Server: mail.clear-code.com X-Spamd-Result: default: False [2.90 / 999.00]; SUSPICIOUS_RECIPS(1.50)[]; MID_CONTAINS_FROM(1.00)[]; MV_CASE(0.50)[]; MIME_GOOD(-0.10)[text/plain]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:2518, ipnet:2404:7a80::/29, country:JP]; RCVD_COUNT_ZERO(0.00)[0]; FREEMAIL_TO(0.00)[gmail.com]; TAGGED_RCPT(0.00)[]; ARC_NA(0.00)[]; FREEMAIL_ENVRCPT(0.00)[gmail.com]; URIBL_BLOCKED(0.00)[localhost:helo,postgresql.org:url]; FROM_HAS_DN(0.00)[]; FREEMAIL_CC(0.00)[gmail.com,paquier.xyz,dunslane.net,postgresql.org]; RCPT_COUNT_FIVE(0.00)[6]; FROM_EQ_ENVFROM(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; TO_DN_NONE(0.00)[]; SURBL_MULTI_FAIL(0.00)[postgresql.org:server fail,localhost:server fail] X-Rspamd-Action: no action List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, In "Re: Make COPY format extendable: Extract COPY TO format implementations" on Fri, 22 Dec 2023 10:58:05 +0800, Junwang Zhao wrote: >> 1. Add an opaque space for custom COPY TO handler >> * Add CopyToState{Get,Set}Opaque() >> https://github.com/kou/postgres/commit/5a610b6a066243f971e029432db67152cfe5e944 >> >> 2. Export CopyToState::attnumlist >> * Add CopyToStateGetAttNumList() >> https://github.com/kou/postgres/commit/15fcba8b4e95afa86edb3f677a7bdb1acb1e7688 >> >> 3. Export CopySend*() >> * Rename CopySend*() to CopyToStateSend*() and export them >> * Exception: CopySendEndOfRow() to CopyToStateFlush() because >> it just flushes the internal buffer now. >> https://github.com/kou/postgres/commit/289a5640135bde6733a1b8e2c412221ad522901e >> > I guess the purpose of these helpers is to avoid expose CopyToState to > copy.h, Yes. > but I > think expose CopyToState to user might make life easier, users might want to use > the memory contexts of the structure (though I agree not all the > fields are necessary > for extension handers). OK. I don't object it as I said in another e-mail: https://www.postgresql.org/message-id/flat/20240110.120644.1876591646729327180.kou%40clear-code.com#d923173e9625c20319750155083cbd72 >> 2. Need an opaque space like IndexScanDesc::opaque does >> >> * A custom COPY TO handler needs to keep its data > > I once thought users might want to parse their own options, maybe this > is a use case for this opaque space. Good catch! I forgot to suggest a callback for custom format options. How about the following API? ---- ... typedef bool (*CopyToProcessOption_function) (CopyToState cstate, DefElem *defel); ... typedef bool (*CopyFromProcessOption_function) (CopyFromState cstate, DefElem *defel); typedef struct CopyToFormatRoutine { ... CopyToProcessOption_function process_option_fn; } CopyToFormatRoutine; typedef struct CopyFromFormatRoutine { ... CopyFromProcessOption_function process_option_fn; } CopyFromFormatRoutine; ---- ---- diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index e7597894bf..1aa8b62551 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -416,6 +416,7 @@ void ProcessCopyOptions(ParseState *pstate, CopyFormatOptions *opts_out, bool is_from, + void *cstate, /* CopyToState* for !is_from, CopyFromState* for is_from */ List *options) { bool format_specified = false; @@ -593,11 +594,19 @@ ProcessCopyOptions(ParseState *pstate, parser_errposition(pstate, defel->location))); } else - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("option \"%s\" not recognized", - defel->defname), - parser_errposition(pstate, defel->location))); + { + bool processed; + if (is_from) + processed = opts_out->from_ops->process_option_fn(cstate, defel); + else + processed = opts_out->to_ops->process_option_fn(cstate, defel); + if (!processed) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("option \"%s\" not recognized", + defel->defname), + parser_errposition(pstate, defel->location))); + } } /* ---- > For the name, I thought private_data might be a better candidate than > opaque, but I do not insist. I don't have a strong opinion for this. Here are the number of headers that use "private_data" and "opaque": $ grep -r private_data --files-with-matches src/include | wc -l 6 $ grep -r opaque --files-with-matches src/include | wc -l 38 It seems that we use "opaque" than "private_data" in general. but it seems that we use "opaque" than "private_data" in our code. > Do you use the arrow library to control the memory? Yes. > Is there a way that > we can let the arrow use postgres' memory context? Yes. Apache Arrow C++ provides a memory pool feature and we can implement PostgreSQL's memory context based memory pool for this. (But this is a custom COPY TO/FROM handler's implementation details.) > I'm not sure this > is necessary, just raise the question for discussion. Could you clarify what should we discuss? We should require that COPY TO/FROM handlers should use PostgreSQL's memory context for all internal memory allocations? > +PG_FUNCTION_INFO_V1(copy_testfmt_handler); > +Datum > +copy_testfmt_handler(PG_FUNCTION_ARGS) > +{ > + bool is_from = PG_GETARG_BOOL(0); > + CopyFormatRoutine *cp = makeNode(CopyFormatRoutine);; > + > > extra semicolon. I noticed it too :-) But I ignored it because the current implementation is only for discussion. We know that it may be dirty. Thanks, -- kou