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 1rSvMy-00GoKB-L2 for pgsql-hackers@arkaria.postgresql.org; Thu, 25 Jan 2024 08:45:57 +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 1rSvMx-00EHOi-Jz for pgsql-hackers@arkaria.postgresql.org; Thu, 25 Jan 2024 08:45:55 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rSvMx-00EHOZ-AE for pgsql-hackers@lists.postgresql.org; Thu, 25 Jan 2024 08:45:55 +0000 Received: from mail.clear-code.com ([153.126.206.245]) by makus.postgresql.org with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rSvMt-003Gqg-B7 for pgsql-hackers@postgresql.org; Thu, 25 Jan 2024 08:45:54 +0000 Received: from localhost (unknown [IPv6:2404:7a80:89c1:1200:6af9:2266:1443:f149]) by mail.clear-code.com (Postfix) with ESMTPSA id D6DB6612556; Thu, 25 Jan 2024 17:45:45 +0900 (JST) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.clear-code.com D6DB6612556 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=clear-code.com; s=default; t=1706172346; bh=nkKnu71i3MNUFvmvaoI2nCoInmb4agC3SviU884whiM=; h=Date:To:Cc:Subject:From:In-Reply-To:References:From; b=aPyztQUxNL8z/IzJhm7eM7GdznDbonpUQdeyn0M4rjg6BysN4AUlheifEXX7du2dB 2Ft6IACo8xx6CrUGWf3sE8LfOGFlUGvcLpD6jgBz6PeMq+B4X/rJmvfrig0X7+EgoJ Mc89sOfCj0tYFvYUFLavkrYICzN+05yAXB+cbd/U= Date: Thu, 25 Jan 2024 17:45:43 +0900 (JST) Message-Id: <20240125.174543.1042528588176841299.kou@clear-code.com> To: michael@paquier.xyz Cc: andrew@dunslane.net, sawada.mshk@gmail.com, zhjwpku@gmail.com, 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: <10025bac-158c-ffe7-fbec-32b42629121f@dunslane.net> <20240124.231726.1771099323950062661.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: D6DB6612556 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]; ASN(0.00)[asn:2518, ipnet:2404:7a80::/29, country:JP]; MIME_TRACE(0.00)[0:+]; ARC_NA(0.00)[]; RCVD_COUNT_ZERO(0.00)[0]; TAGGED_RCPT(0.00)[]; FREEMAIL_ENVRCPT(0.00)[gmail.com]; URIBL_BLOCKED(0.00)[paquier.xyz:email,localhost:helo]; TO_MATCH_ENVRCPT_ALL(0.00)[]; FREEMAIL_CC(0.00)[dunslane.net,gmail.com,postgresql.org]; RCPT_COUNT_FIVE(0.00)[6]; FROM_HAS_DN(0.00)[]; TO_DN_NONE(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; SURBL_MULTI_FAIL(0.00)[paquier.xyz: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 Thu, 25 Jan 2024 12:17:55 +0900, Michael Paquier wrote: > +typedef bool (*CopyToProcessOption_function) (CopyToState cstate, DefElem *defel); > +typedef int16 (*CopyToGetFormat_function) (CopyToState cstate); > +typedef void (*CopyToStart_function) (CopyToState cstate, TupleDesc tupDesc); > +typedef void (*CopyToOneRow_function) (CopyToState cstate, TupleTableSlot *slot); > +typedef void (*CopyToEnd_function) (CopyToState cstate); > > We don't really need a set of typedefs here, let's put the definitions > in the CopyToRoutine struct instead. OK. I'll do it. > +extern CopyToRoutine CopyToRoutineText; > +extern CopyToRoutine CopyToRoutineCSV; > +extern CopyToRoutine CopyToRoutineBinary; > > All that should IMO remain in copyto.c and copyfrom.c in the initial > patch doing the refactoring. Why not using a fetch function instead > that uses a string in input? Then you can call that once after > parsing the List of options in ProcessCopyOptions(). OK. How about the following for the fetch function signature? extern CopyToRoutine *GetBuiltinCopyToRoutine(const char *format); We may introduce an enum and use it: typedef enum CopyBuiltinFormat { COPY_BUILTIN_FORMAT_TEXT = 0, COPY_BUILTIN_FORMAT_CSV, COPY_BUILTIN_FORMAT_BINARY, } CopyBuiltinFormat; extern CopyToRoutine *GetBuiltinCopyToRoutine(CopyBuiltinFormat format); > +/* All "text" and "csv" options are parsed in ProcessCopyOptions(). We may > + * move the code to here later. */ > Some areas, like this comment, are written in an incorrect format. Oh, sorry. I assumed that the comment style was adjusted by pgindent. I'll use the following style: /* * ... */ > + getTypeBinaryOutputInfo(attr->atttypid, &out_func_oid, &isvarlena); > + fmgr_info(out_func_oid, &cstate->out_functions[attnum - 1]); > > Actually, this split is interesting. It is possible for a custom > format to plug in a custom set of out functions. Did you make use of > something custom for your own stuff? I didn't. My PoC custom COPY format handler for Apache Arrow just handles integer and text for now. It doesn't use cstate->out_functions because cstate->out_functions may not return a valid binary format value for Apache Arrow. So it formats each value by itself. I'll chose one of them for a custom type (that isn't supported by Apache Arrow, e.g. PostGIS types): 1. Report an unsupported error 2. Call output function for Apache Arrow provided by the custom type > Actually, could it make sense to > split the assignment of cstate->out_functions into its own callback? Yes. Because we need to use getTypeBinaryOutputInfo() for "binary" and use getTypeOutputInfo() for "text" and "csv". > Sure, that's part of the start phase, but at least it would make clear > that a custom method *has* to assign these OIDs to work. The patch > implies that as a rule, without a comment that CopyToStart *must* set > up these OIDs. CopyToStart doesn't need to set up them if the handler doesn't use cstate->out_functions. > I think that 0001 and 0005 should be handled first, as pieces > independent of the rest. Then we could move on with 0002~0004 and > 0006~0008. OK. I'll focus on 0001 and 0005 for now. I'll restart 0002-0004/0006-0008 after 0001 and 0005 are accepted. Thanks, -- kou