Make COPY format extendable: Extract COPY TO format implementations

Started by Sutou Kouheiover 2 years ago334 messages
Jump to latest
#1Sutou Kouhei
kou@clear-code.com

Hi,

I want to work on making COPY format extendable. I attach
the first patch for it. I'll send more patches after this is
merged.

Background:

Currently, COPY TO/FROM supports only "text", "csv" and
"binary" formats. There are some requests to support more
COPY formats. For example:

* 2023-11: JSON and JSON lines [1]/messages/by-id/24e3ee88-ec1e-421b-89ae-8a47ee0d2df1@joeconway.com
* 2022-04: Apache Arrow [2]/messages/by-id/CAGrfaBVyfm0wPzXVqm0=h5uArYh9N_ij+sVpUtDHqkB=VyB3jw@mail.gmail.com
* 2018-02: Apache Avro, Apache Parquet and Apache ORC [3]/messages/by-id/20180210151304.fonjztsynewldfba@gmail.com

(FYI: I want to add support for Apache Arrow.)

There were discussions how to add support for more formats. [3]/messages/by-id/20180210151304.fonjztsynewldfba@gmail.com[4]/messages/by-id/3741749.1655952719@sss.pgh.pa.us
In these discussions, we got a consensus about making COPY
format extendable.

But it seems that nobody works on this yet. So I want to
work on this. (If there is anyone who wants to work on this
together, I'm happy.)

Summary:

The attached patch introduces CopyToFormatOps struct that is
similar to TupleTableSlotOps for TupleTableSlot but
CopyToFormatOps is for COPY TO format. CopyToFormatOps has
routines to implement a COPY TO format.

The attached patch doesn't change:

* the current behavior (all existing tests are still passed
without changing them)
* the existing "text", "csv" and "binary" format output
implementations including local variable names (the
attached patch just move them and adjust indent)
* performance (no significant loss of performance)

In other words, this is just a refactoring for further
changes to make COPY format extendable. If I use "complete
the task and then request reviews for it" approach, it will
be difficult to review because changes for it will be
large. So I want to work on this step by step. Is it
acceptable?

TODOs that should be done in subsequent patches:

* Add some CopyToState readers such as CopyToStateGetDest(),
CopyToStateGetAttnums() and CopyToStateGetOpts()
(We will need to consider which APIs should be exported.)
(This is for implemeing COPY TO format by extension.)
* Export CopySend*() in src/backend/commands/copyto.c
(This is for implemeing COPY TO format by extension.)
* Add API to register a new COPY TO format implementation
* Add "CREATE XXX" to register a new COPY TO format (or COPY
TO/FROM format) implementation
("CREATE COPY HANDLER" was suggested in [5]/messages/by-id/20180211211235.5x3jywe5z3lkgcsr@alap3.anarazel.de.)
* Same for COPY FROM

Performance:

We got a consensus about making COPY format extendable but
we should care about performance. [6]/messages/by-id/3741749.1655952719@sss.pgh.pa.us

I think that step 1 ought to be to convert the existing
formats into plug-ins, and demonstrate that there's no
significant loss of performance.

So I measured COPY TO time with/without this change. You can
see there is no significant loss of performance.

Data: Random 32 bit integers:

CREATE TABLE data (int32 integer);
INSERT INTO data
SELECT random() * 10000
FROM generate_series(1, ${n_records});

The number of records: 100K, 1M and 10M

100K without this change:

format,elapsed time (ms)
text,22.527
csv,23.822
binary,24.806

100K with this change:

format,elapsed time (ms)
text,22.919
csv,24.643
binary,24.705

1M without this change:

format,elapsed time (ms)
text,223.457
csv,233.583
binary,242.687

1M with this change:

format,elapsed time (ms)
text,224.591
csv,233.964
binary,247.164

10M without this change:

format,elapsed time (ms)
text,2330.383
csv,2411.394
binary,2590.817

10M with this change:

format,elapsed time (ms)
text,2231.307
csv,2408.067
binary,2473.617

[1]: /messages/by-id/24e3ee88-ec1e-421b-89ae-8a47ee0d2df1@joeconway.com
[2]: /messages/by-id/CAGrfaBVyfm0wPzXVqm0=h5uArYh9N_ij+sVpUtDHqkB=VyB3jw@mail.gmail.com
[3]: /messages/by-id/20180210151304.fonjztsynewldfba@gmail.com
[4]: /messages/by-id/3741749.1655952719@sss.pgh.pa.us
[5]: /messages/by-id/20180211211235.5x3jywe5z3lkgcsr@alap3.anarazel.de
[6]: /messages/by-id/3741749.1655952719@sss.pgh.pa.us

Thanks,
--
kou

Attachments:

v1-0001-Extract-COPY-TO-format-implementations.patchtext/x-patch; charset=us-asciiDownload+269-157
#2Nathan Bossart
nathandbossart@gmail.com
In reply to: Sutou Kouhei (#1)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Mon, Dec 04, 2023 at 03:35:48PM +0900, Sutou Kouhei wrote:

I want to work on making COPY format extendable. I attach
the first patch for it. I'll send more patches after this is
merged.

Given the current discussion about adding JSON, I think this could be a
nice bit of refactoring that could ultimately open the door to providing
other COPY formats via shared libraries.

In other words, this is just a refactoring for further
changes to make COPY format extendable. If I use "complete
the task and then request reviews for it" approach, it will
be difficult to review because changes for it will be
large. So I want to work on this step by step. Is it
acceptable?

I think it makes sense to do this part independently, but we should be
careful to design this with the follow-up tasks in mind.

So I measured COPY TO time with/without this change. You can
see there is no significant loss of performance.

Data: Random 32 bit integers:

CREATE TABLE data (int32 integer);
INSERT INTO data
SELECT random() * 10000
FROM generate_series(1, ${n_records});

Seems encouraging. I assume the performance concerns stem from the use of
function pointers. Or was there something else?

--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com

#3Sutou Kouhei
kou@clear-code.com
In reply to: Nathan Bossart (#2)
Re: Make COPY format extendable: Extract COPY TO format implementations

Hi,

Thanks for replying to this proposal!

In <20231205182458.GC2757816@nathanxps13>
"Re: Make COPY format extendable: Extract COPY TO format implementations" on Tue, 5 Dec 2023 12:24:58 -0600,
Nathan Bossart <nathandbossart@gmail.com> wrote:

I think it makes sense to do this part independently, but we should be
careful to design this with the follow-up tasks in mind.

OK. I'll keep updating the "TODOs" section in the original
e-mail. It also includes design in the follow-up tasks. We
can discuss the design separately from the patches
submitting. (The current submitted patch just focuses on
refactoring but we can discuss the final design.)

I assume the performance concerns stem from the use of
function pointers. Or was there something else?

I think so too.

The original e-mail that mentioned the performance concern
[1]: /messages/by-id/3741749.1655952719@sss.pgh.pa.us
pointers might be concerned.

If the currently supported formats ("text", "csv" and
"binary") are implemented as an extension, it may have more
concerns but we will keep them as built-in formats for
compatibility. So I think that no more concerns exist for
these formats.

[1]: /messages/by-id/3741749.1655952719@sss.pgh.pa.us

Thanks,
--
kou

#4Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#3)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Wed, Dec 6, 2023 at 10:45 AM Sutou Kouhei <kou@clear-code.com> wrote:

Hi,

Thanks for replying to this proposal!

In <20231205182458.GC2757816@nathanxps13>
"Re: Make COPY format extendable: Extract COPY TO format implementations" on Tue, 5 Dec 2023 12:24:58 -0600,
Nathan Bossart <nathandbossart@gmail.com> wrote:

I think it makes sense to do this part independently, but we should be
careful to design this with the follow-up tasks in mind.

OK. I'll keep updating the "TODOs" section in the original
e-mail. It also includes design in the follow-up tasks. We
can discuss the design separately from the patches
submitting. (The current submitted patch just focuses on
refactoring but we can discuss the final design.)

I assume the performance concerns stem from the use of
function pointers. Or was there something else?

I think so too.

The original e-mail that mentioned the performance concern
[1] didn't say about the reason but the use of function
pointers might be concerned.

If the currently supported formats ("text", "csv" and
"binary") are implemented as an extension, it may have more
concerns but we will keep them as built-in formats for
compatibility. So I think that no more concerns exist for
these formats.

For the modern formats(parquet, orc, avro, etc.), will they be
implemented as extensions or in core?

The patch looks good except for a pair of extra curly braces.

[1]: /messages/by-id/3741749.1655952719@sss.pgh.pa.us

Thanks,
--
kou

--
Regards
Junwang Zhao

#5Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#4)
Re: Make COPY format extendable: Extract COPY TO format implementations

Hi,

In <CAEG8a3Jf7kPV3ez5OHu-pFGscKfVyd9KkubMF199etkfz=EPRg@mail.gmail.com>
"Re: Make COPY format extendable: Extract COPY TO format implementations" on Wed, 6 Dec 2023 11:18:35 +0800,
Junwang Zhao <zhjwpku@gmail.com> wrote:

For the modern formats(parquet, orc, avro, etc.), will they be
implemented as extensions or in core?

I think that they should be implemented as extensions
because they will depend of external libraries and may not
use C. For example, C++ will be used for Apache Parquet
because the official Apache Parquet C++ implementation
exists but the C implementation doesn't.

(I can implement an extension for Apache Parquet after we
complete this feature. I'll implement an extension for
Apache Arrow with the official Apache Arrow C++
implementation. And it's easy that we convert Apache Arrow
data to Apache Parquet with the official Apache Parquet
implementation.)

The patch looks good except for a pair of extra curly braces.

Thanks for the review! I attach the v2 patch that removes
extra curly braces for "if (isnull)".

Thanks,
--
kou

Attachments:

v2-0001-Extract-COPY-TO-format-implementations.patchtext/x-patch; charset=us-asciiDownload+265-157
#6Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#5)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Wed, Dec 6, 2023 at 2:19 PM Sutou Kouhei <kou@clear-code.com> wrote:

Hi,

In <CAEG8a3Jf7kPV3ez5OHu-pFGscKfVyd9KkubMF199etkfz=EPRg@mail.gmail.com>
"Re: Make COPY format extendable: Extract COPY TO format implementations" on Wed, 6 Dec 2023 11:18:35 +0800,
Junwang Zhao <zhjwpku@gmail.com> wrote:

For the modern formats(parquet, orc, avro, etc.), will they be
implemented as extensions or in core?

I think that they should be implemented as extensions
because they will depend of external libraries and may not
use C. For example, C++ will be used for Apache Parquet
because the official Apache Parquet C++ implementation
exists but the C implementation doesn't.

(I can implement an extension for Apache Parquet after we
complete this feature. I'll implement an extension for
Apache Arrow with the official Apache Arrow C++
implementation. And it's easy that we convert Apache Arrow
data to Apache Parquet with the official Apache Parquet
implementation.)

The patch looks good except for a pair of extra curly braces.

Thanks for the review! I attach the v2 patch that removes
extra curly braces for "if (isnull)".

For the extra curly braces, I mean the following code block in
CopyToFormatBinaryStart:

+ {        <-- I thought this is useless?
+ /* Generate header for a binary copy */
+ int32 tmp;
+
+ /* Signature */
+ CopySendData(cstate, BinarySignature, 11);
+ /* Flags field */
+ tmp = 0;
+ CopySendInt32(cstate, tmp);
+ /* No header extension */
+ tmp = 0;
+ CopySendInt32(cstate, tmp);
+ }

Thanks,
--
kou

--
Regards
Junwang Zhao

#7Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#6)
Re: Make COPY format extendable: Extract COPY TO format implementations

Hi,

In <CAEG8a3K9dE2gt3+K+h=DwTqMenR84aeYuYS+cty3SR3LAeDBAQ@mail.gmail.com>
"Re: Make COPY format extendable: Extract COPY TO format implementations" on Wed, 6 Dec 2023 15:11:34 +0800,
Junwang Zhao <zhjwpku@gmail.com> wrote:

For the extra curly braces, I mean the following code block in
CopyToFormatBinaryStart:

+ {        <-- I thought this is useless?
+ /* Generate header for a binary copy */
+ int32 tmp;
+
+ /* Signature */
+ CopySendData(cstate, BinarySignature, 11);
+ /* Flags field */
+ tmp = 0;
+ CopySendInt32(cstate, tmp);
+ /* No header extension */
+ tmp = 0;
+ CopySendInt32(cstate, tmp);
+ }

Oh, I see. I've removed and attach the v3 patch. In general,
I don't change variable name and so on in this patch. I just
move codes in this patch. But I also removed the "tmp"
variable for this case because I think that the name isn't
suitable for larger scope. (I think that "tmp" is acceptable
in a small scope like the above code.)

New code:

/* Generate header for a binary copy */
/* Signature */
CopySendData(cstate, BinarySignature, 11);
/* Flags field */
CopySendInt32(cstate, 0);
/* No header extension */
CopySendInt32(cstate, 0);

Thanks,
--
kou

Attachments:

v3-0001-Extract-COPY-TO-format-implementations.patchtext/x-patch; charset=us-asciiDownload+259-157
#8Daniel Verite
daniel@manitou-mail.org
In reply to: Sutou Kouhei (#1)
Re: Make COPY format extendable: Extract COPY TO format implementations

Sutou Kouhei wrote:

* 2022-04: Apache Arrow [2]
* 2018-02: Apache Avro, Apache Parquet and Apache ORC [3]

(FYI: I want to add support for Apache Arrow.)

There were discussions how to add support for more formats. [3][4]
In these discussions, we got a consensus about making COPY
format extendable.

These formats seem all column-oriented whereas COPY is row-oriented
at the protocol level [1]https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-COPY.
With regard to the procotol, how would it work to support these formats?

[1]: https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-COPY

Best regards,
--
Daniel Vérité
https://postgresql.verite.pro/
Twitter: @DanielVerite

#9Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#7)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Wed, Dec 6, 2023 at 3:28 PM Sutou Kouhei <kou@clear-code.com> wrote:

Hi,

In <CAEG8a3K9dE2gt3+K+h=DwTqMenR84aeYuYS+cty3SR3LAeDBAQ@mail.gmail.com>
"Re: Make COPY format extendable: Extract COPY TO format implementations" on Wed, 6 Dec 2023 15:11:34 +0800,
Junwang Zhao <zhjwpku@gmail.com> wrote:

For the extra curly braces, I mean the following code block in
CopyToFormatBinaryStart:

+ {        <-- I thought this is useless?
+ /* Generate header for a binary copy */
+ int32 tmp;
+
+ /* Signature */
+ CopySendData(cstate, BinarySignature, 11);
+ /* Flags field */
+ tmp = 0;
+ CopySendInt32(cstate, tmp);
+ /* No header extension */
+ tmp = 0;
+ CopySendInt32(cstate, tmp);
+ }

Oh, I see. I've removed and attach the v3 patch. In general,
I don't change variable name and so on in this patch. I just
move codes in this patch. But I also removed the "tmp"
variable for this case because I think that the name isn't
suitable for larger scope. (I think that "tmp" is acceptable
in a small scope like the above code.)

New code:

/* Generate header for a binary copy */
/* Signature */
CopySendData(cstate, BinarySignature, 11);
/* Flags field */
CopySendInt32(cstate, 0);
/* No header extension */
CopySendInt32(cstate, 0);

Thanks,
--
kou

Hi Kou,

I read the thread[1]/messages/by-id/20180211211235.5x3jywe5z3lkgcsr@alap3.anarazel.de -- Regards Junwang Zhao you posted and I think Andres's suggestion sounds great.

Should we extract both *copy to* and *copy from* for the first step, in that
case we can add the pg_copy_handler catalog smoothly later.

Attached V4 adds 'extract copy from' and it passed the cirrus ci,
please take a look.

I added a hook *copy_from_end* but this might be removed later if not used.

[1]: /messages/by-id/20180211211235.5x3jywe5z3lkgcsr@alap3.anarazel.de -- Regards Junwang Zhao
--
Regards
Junwang Zhao

Attachments:

v4-0001-Extract-COPY-handlers.patchapplication/octet-stream; name=v4-0001-Extract-COPY-handlers.patchDownload+619-413
#10Junwang Zhao
zhjwpku@gmail.com
In reply to: Daniel Verite (#8)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Wed, Dec 6, 2023 at 8:32 PM Daniel Verite <daniel@manitou-mail.org> wrote:

Sutou Kouhei wrote:

* 2022-04: Apache Arrow [2]
* 2018-02: Apache Avro, Apache Parquet and Apache ORC [3]

(FYI: I want to add support for Apache Arrow.)

There were discussions how to add support for more formats. [3][4]
In these discussions, we got a consensus about making COPY
format extendable.

These formats seem all column-oriented whereas COPY is row-oriented
at the protocol level [1].
With regard to the procotol, how would it work to support these formats?

They have kind of *RowGroup* concepts, a bunch of rows goes to a RowBatch
and the data of the same column goes together.

I think they should fit the COPY semantics and there are some FDW out there for
these modern formats, like [1]https://github.com/adjust/parquet_fdw. If we support COPY to deal with the
format, it will
be easier to interact with them(without creating
server/usermapping/foreign table).

[1]: https://github.com/adjust/parquet_fdw

[1] https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-COPY

Best regards,
--
Daniel Vérité
https://postgresql.verite.pro/
Twitter: @DanielVerite

--
Regards
Junwang Zhao

#11Michael Paquier
michael@paquier.xyz
In reply to: Junwang Zhao (#9)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Wed, Dec 06, 2023 at 10:07:51PM +0800, Junwang Zhao wrote:

I read the thread[1] you posted and I think Andres's suggestion sounds great.

Should we extract both *copy to* and *copy from* for the first step, in that
case we can add the pg_copy_handler catalog smoothly later.

Attached V4 adds 'extract copy from' and it passed the cirrus ci,
please take a look.

I added a hook *copy_from_end* but this might be removed later if not used.

[1]: /messages/by-id/20180211211235.5x3jywe5z3lkgcsr@alap3.anarazel.de

I was looking at the differences between v3 posted by Sutou-san and
v4 from you, seeing that:

+/* Routines for a COPY HANDLER implementation. */
+typedef struct CopyHandlerOps
 {
     /* Called when COPY TO is started. This will send a header. */
-    void        (*start) (CopyToState cstate, TupleDesc tupDesc);
+    void        (*copy_to_start) (CopyToState cstate, TupleDesc tupDesc);
     /* Copy one row for COPY TO. */
-    void        (*one_row) (CopyToState cstate, TupleTableSlot *slot);
+    void        (*copy_to_one_row) (CopyToState cstate, TupleTableSlot *slot);
     /* Called when COPY TO is ended. This will send a trailer. */
-    void        (*end) (CopyToState cstate);
-} CopyToFormatOps;
+    void        (*copy_to_end) (CopyToState cstate);
+
+    void        (*copy_from_start) (CopyFromState cstate, TupleDesc tupDesc);
+    bool        (*copy_from_next) (CopyFromState cstate, ExprContext *econtext,
+                                    Datum *values, bool *nulls);
+    void        (*copy_from_error_callback) (CopyFromState cstate);
+    void        (*copy_from_end) (CopyFromState cstate);
+} CopyHandlerOps;

And we've spent a good deal of time refactoring the copy code so as
the logic behind TO and FROM is split. Having a set of routines that
groups both does not look like a step in the right direction to me,
and v4 is an attempt at solving two problems, while v3 aims to improve
one case. It seems to me that each callback portion should be focused
on staying in its own area of the code, aka copyfrom*.c or copyto*.c.
--
Michael

#12Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#9)
Re: Make COPY format extendable: Extract COPY TO format implementations

Hi,

In <CAEG8a3LSRhK601Bn50u71BgfNWm4q3kv-o-KEq=hrbyLbY_EsA@mail.gmail.com>
"Re: Make COPY format extendable: Extract COPY TO format implementations" on Wed, 6 Dec 2023 22:07:51 +0800,
Junwang Zhao <zhjwpku@gmail.com> wrote:

Should we extract both *copy to* and *copy from* for the first step, in that
case we can add the pg_copy_handler catalog smoothly later.

I don't object it (mixing TO/FROM changes to one patch) but
it may make review difficult. Is it acceptable?

FYI: I planed that I implement TO part, and then FROM part,
and then unify TO/FROM parts if needed. [1]/messages/by-id/20231204.153548.2126325458835528809.kou@clear-code.com

Attached V4 adds 'extract copy from' and it passed the cirrus ci,
please take a look.

Thanks. Here are my comments:

+		/*
+			* Error is relevant to a particular line.
+			*
+			* If line_buf still contains the correct line, print it.
+			*/
+		if (cstate->line_buf_valid)

We need to fix the indentation.

+CopyFromFormatBinaryStart(CopyFromState cstate, TupleDesc tupDesc)
+{
+	FmgrInfo   *in_functions;
+	Oid		   *typioparams;
+	Oid			in_func_oid;
+	AttrNumber	num_phys_attrs;
+
+	/*
+	 * Pick up the required catalog information for each attribute in the
+	 * relation, including the input function, the element type (to pass to
+	 * the input function), and info about defaults and constraints. (Which
+	 * input function we use depends on text/binary format choice.)
+	 */
+	num_phys_attrs = tupDesc->natts;
+	in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
+	typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid));

We need to update the comment because defaults and
constraints aren't picked up here.

+CopyFromFormatTextStart(CopyFromState cstate, TupleDesc tupDesc)

...

+	/*
+	 * Pick up the required catalog information for each attribute in the
+	 * relation, including the input function, the element type (to pass to
+	 * the input function), and info about defaults and constraints. (Which
+	 * input function we use depends on text/binary format choice.)
+	 */
+	in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
+	typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid));

ditto.

@@ -1716,15 +1776,6 @@ BeginCopyFrom(ParseState *pstate,
ReceiveCopyBinaryHeader(cstate);
}

I think that this block should be moved to
CopyFromFormatBinaryStart() too. But we need to run it after
we setup inputs such as data_source_cb, pipe and filename...

+/* Routines for a COPY HANDLER implementation. */
+typedef struct CopyHandlerOps
+{
+	/* Called when COPY TO is started. This will send a header. */
+	void		(*copy_to_start) (CopyToState cstate, TupleDesc tupDesc);
+
+	/* Copy one row for COPY TO. */
+	void		(*copy_to_one_row) (CopyToState cstate, TupleTableSlot *slot);
+
+	/* Called when COPY TO is ended. This will send a trailer. */
+	void		(*copy_to_end) (CopyToState cstate);
+
+	void		(*copy_from_start) (CopyFromState cstate, TupleDesc tupDesc);
+	bool		(*copy_from_next) (CopyFromState cstate, ExprContext *econtext,
+			 					   Datum *values, bool *nulls);
+	void		(*copy_from_error_callback) (CopyFromState cstate);
+	void		(*copy_from_end) (CopyFromState cstate);
+} CopyHandlerOps;

It seems that "copy_" prefix is redundant. Should we use
"to_start" instead of "copy_to_start" and so on?

BTW, it seems that "COPY FROM (FORMAT json)" may not be implemented. [2]/messages/by-id/CALvfUkBxTYy5uWPFVwpk_7ii2zgT07t3d-yR_cy4sfrrLU=kcg@mail.gmail.com
We may need to care about NULL copy_from_* cases.

I added a hook *copy_from_end* but this might be removed later if not used.

It may be useful to clean up resources for COPY FROM but the
patch doesn't call the copy_from_end. How about removing it
for now? We can add it and call it from EndCopyFrom() later?
Because it's not needed for now.

I think that we should focus on refactoring instead of
adding a new feature in this patch.

[1]: /messages/by-id/20231204.153548.2126325458835528809.kou@clear-code.com
[2]: /messages/by-id/CALvfUkBxTYy5uWPFVwpk_7ii2zgT07t3d-yR_cy4sfrrLU=kcg@mail.gmail.com

Thanks,
--
kou

#13Junwang Zhao
zhjwpku@gmail.com
In reply to: Michael Paquier (#11)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Thu, Dec 7, 2023 at 8:39 AM Michael Paquier <michael@paquier.xyz> wrote:

On Wed, Dec 06, 2023 at 10:07:51PM +0800, Junwang Zhao wrote:

I read the thread[1] you posted and I think Andres's suggestion sounds great.

Should we extract both *copy to* and *copy from* for the first step, in that
case we can add the pg_copy_handler catalog smoothly later.

Attached V4 adds 'extract copy from' and it passed the cirrus ci,
please take a look.

I added a hook *copy_from_end* but this might be removed later if not used.

[1]: /messages/by-id/20180211211235.5x3jywe5z3lkgcsr@alap3.anarazel.de

I was looking at the differences between v3 posted by Sutou-san and
v4 from you, seeing that:

+/* Routines for a COPY HANDLER implementation. */
+typedef struct CopyHandlerOps
{
/* Called when COPY TO is started. This will send a header. */
-    void        (*start) (CopyToState cstate, TupleDesc tupDesc);
+    void        (*copy_to_start) (CopyToState cstate, TupleDesc tupDesc);
/* Copy one row for COPY TO. */
-    void        (*one_row) (CopyToState cstate, TupleTableSlot *slot);
+    void        (*copy_to_one_row) (CopyToState cstate, TupleTableSlot *slot);
/* Called when COPY TO is ended. This will send a trailer. */
-    void        (*end) (CopyToState cstate);
-} CopyToFormatOps;
+    void        (*copy_to_end) (CopyToState cstate);
+
+    void        (*copy_from_start) (CopyFromState cstate, TupleDesc tupDesc);
+    bool        (*copy_from_next) (CopyFromState cstate, ExprContext *econtext,
+                                    Datum *values, bool *nulls);
+    void        (*copy_from_error_callback) (CopyFromState cstate);
+    void        (*copy_from_end) (CopyFromState cstate);
+} CopyHandlerOps;

And we've spent a good deal of time refactoring the copy code so as
the logic behind TO and FROM is split. Having a set of routines that
groups both does not look like a step in the right direction to me,

The point of this refactor (from my view) is to make it possible to add new
copy handlers in extensions, just like access method. As Andres suggested,
a system catalog like *pg_copy_handler*, if we split TO and FROM into two
sets of routines, does that mean we have to create two catalog(
pg_copy_from_handler and pg_copy_to_handler)?

and v4 is an attempt at solving two problems, while v3 aims to improve
one case. It seems to me that each callback portion should be focused
on staying in its own area of the code, aka copyfrom*.c or copyto*.c.
--
Michael

--
Regards
Junwang Zhao

#14Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#12)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Thu, Dec 7, 2023 at 1:05 PM Sutou Kouhei <kou@clear-code.com> wrote:

Hi,

In <CAEG8a3LSRhK601Bn50u71BgfNWm4q3kv-o-KEq=hrbyLbY_EsA@mail.gmail.com>
"Re: Make COPY format extendable: Extract COPY TO format implementations" on Wed, 6 Dec 2023 22:07:51 +0800,
Junwang Zhao <zhjwpku@gmail.com> wrote:

Should we extract both *copy to* and *copy from* for the first step, in that
case we can add the pg_copy_handler catalog smoothly later.

I don't object it (mixing TO/FROM changes to one patch) but
it may make review difficult. Is it acceptable?

FYI: I planed that I implement TO part, and then FROM part,
and then unify TO/FROM parts if needed. [1]

I'm fine with step by step refactoring, let's just wait for more
suggestions.

Attached V4 adds 'extract copy from' and it passed the cirrus ci,
please take a look.

Thanks. Here are my comments:

+             /*
+                     * Error is relevant to a particular line.
+                     *
+                     * If line_buf still contains the correct line, print it.
+                     */
+             if (cstate->line_buf_valid)

We need to fix the indentation.

+CopyFromFormatBinaryStart(CopyFromState cstate, TupleDesc tupDesc)
+{
+     FmgrInfo   *in_functions;
+     Oid                *typioparams;
+     Oid                     in_func_oid;
+     AttrNumber      num_phys_attrs;
+
+     /*
+      * Pick up the required catalog information for each attribute in the
+      * relation, including the input function, the element type (to pass to
+      * the input function), and info about defaults and constraints. (Which
+      * input function we use depends on text/binary format choice.)
+      */
+     num_phys_attrs = tupDesc->natts;
+     in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
+     typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid));

We need to update the comment because defaults and
constraints aren't picked up here.

+CopyFromFormatTextStart(CopyFromState cstate, TupleDesc tupDesc)

...

+     /*
+      * Pick up the required catalog information for each attribute in the
+      * relation, including the input function, the element type (to pass to
+      * the input function), and info about defaults and constraints. (Which
+      * input function we use depends on text/binary format choice.)
+      */
+     in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
+     typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid));

ditto.

@@ -1716,15 +1776,6 @@ BeginCopyFrom(ParseState *pstate,
ReceiveCopyBinaryHeader(cstate);
}

I think that this block should be moved to
CopyFromFormatBinaryStart() too. But we need to run it after
we setup inputs such as data_source_cb, pipe and filename...

+/* Routines for a COPY HANDLER implementation. */
+typedef struct CopyHandlerOps
+{
+       /* Called when COPY TO is started. This will send a header. */
+       void            (*copy_to_start) (CopyToState cstate, TupleDesc tupDesc);
+
+       /* Copy one row for COPY TO. */
+       void            (*copy_to_one_row) (CopyToState cstate, TupleTableSlot *slot);
+
+       /* Called when COPY TO is ended. This will send a trailer. */
+       void            (*copy_to_end) (CopyToState cstate);
+
+       void            (*copy_from_start) (CopyFromState cstate, TupleDesc tupDesc);
+       bool            (*copy_from_next) (CopyFromState cstate, ExprContext *econtext,
+                                                                  Datum *values, bool *nulls);
+       void            (*copy_from_error_callback) (CopyFromState cstate);
+       void            (*copy_from_end) (CopyFromState cstate);
+} CopyHandlerOps;

It seems that "copy_" prefix is redundant. Should we use
"to_start" instead of "copy_to_start" and so on?

BTW, it seems that "COPY FROM (FORMAT json)" may not be implemented. [2]
We may need to care about NULL copy_from_* cases.

I added a hook *copy_from_end* but this might be removed later if not used.

It may be useful to clean up resources for COPY FROM but the
patch doesn't call the copy_from_end. How about removing it
for now? We can add it and call it from EndCopyFrom() later?
Because it's not needed for now.

I think that we should focus on refactoring instead of
adding a new feature in this patch.

[1]: /messages/by-id/20231204.153548.2126325458835528809.kou@clear-code.com
[2]: /messages/by-id/CALvfUkBxTYy5uWPFVwpk_7ii2zgT07t3d-yR_cy4sfrrLU=kcg@mail.gmail.com

Thanks,
--
kou

--
Regards
Junwang Zhao

#15Andrew Dunstan
andrew@dunslane.net
In reply to: Junwang Zhao (#13)
Re: Make COPY format extendable: Extract COPY TO format implementations

On 2023-12-07 Th 03:37, Junwang Zhao wrote:

The point of this refactor (from my view) is to make it possible to add new
copy handlers in extensions, just like access method. As Andres suggested,
a system catalog like *pg_copy_handler*, if we split TO and FROM into two
sets of routines, does that mean we have to create two catalog(
pg_copy_from_handler and pg_copy_to_handler)?

Surely not. Either have two fields, one for the TO handler and one for
the FROM handler, or a flag on each row indicating if it's a FROM or TO
handler.

cheers

andrew

--
Andrew Dunstan
EDB: https://www.enterprisedb.com

#16Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Andrew Dunstan (#15)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Fri, Dec 8, 2023 at 1:39 AM Andrew Dunstan <andrew@dunslane.net> wrote:

On 2023-12-07 Th 03:37, Junwang Zhao wrote:

The point of this refactor (from my view) is to make it possible to add new
copy handlers in extensions, just like access method. As Andres suggested,
a system catalog like *pg_copy_handler*, if we split TO and FROM into two
sets of routines, does that mean we have to create two catalog(
pg_copy_from_handler and pg_copy_to_handler)?

Surely not. Either have two fields, one for the TO handler and one for
the FROM handler, or a flag on each row indicating if it's a FROM or TO
handler.

True.

But why do we need a system catalog like pg_copy_handler in the first
place? I imagined that an extension can define a handler function
returning a set of callbacks and the parser can lookup the handler
function by name, like FDW and TABLESAMPLE.

Regards,

--
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com

#17Junwang Zhao
zhjwpku@gmail.com
In reply to: Masahiko Sawada (#16)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Fri, Dec 8, 2023 at 3:27 AM Masahiko Sawada <sawada.mshk@gmail.com> wrote:

On Fri, Dec 8, 2023 at 1:39 AM Andrew Dunstan <andrew@dunslane.net> wrote:

On 2023-12-07 Th 03:37, Junwang Zhao wrote:

The point of this refactor (from my view) is to make it possible to add new
copy handlers in extensions, just like access method. As Andres suggested,
a system catalog like *pg_copy_handler*, if we split TO and FROM into two
sets of routines, does that mean we have to create two catalog(
pg_copy_from_handler and pg_copy_to_handler)?

Surely not. Either have two fields, one for the TO handler and one for
the FROM handler, or a flag on each row indicating if it's a FROM or TO
handler.

If we wrap the two fields into a single structure, that will still be in
copy.h, which I think is not necessary. A single routing wrapper should
be enough, the actual implementation still stays separate
copy_[to/from].c files.

True.

But why do we need a system catalog like pg_copy_handler in the first
place? I imagined that an extension can define a handler function
returning a set of callbacks and the parser can lookup the handler
function by name, like FDW and TABLESAMPLE.

I can see FDW related utility commands but no TABLESAMPLE related,
and there is a pg_foreign_data_wrapper system catalog which has
a *fdwhandler* field.

If we want extensions to create a new copy handler, I think
something like pg_copy_hander should be necessary.

Regards,

--
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com

I go one step further to implement the pg_copy_handler, attached V5 is
the implementation with some changes suggested by Kou.

You can also review this on this github pull request [1]https://github.com/zhjwpku/postgres/pull/1/files.

[1]: https://github.com/zhjwpku/postgres/pull/1/files

--
Regards
Junwang Zhao

Attachments:

v5-0001-Extract-COPY-handlers.patchapplication/octet-stream; name=v5-0001-Extract-COPY-handlers.patchDownload+839-418
#18Michael Paquier
michael@paquier.xyz
In reply to: Junwang Zhao (#17)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Fri, Dec 08, 2023 at 10:32:27AM +0800, Junwang Zhao wrote:

I can see FDW related utility commands but no TABLESAMPLE related,
and there is a pg_foreign_data_wrapper system catalog which has
a *fdwhandler* field.

+ */ +CATALOG(pg_copy_handler,4551,CopyHandlerRelationId)

Using a catalog is an over-engineered design. Others have provided
hints about that upthread, but it would be enough to have one or two
handler types that are wrapped around one or two SQL *functions*, like
tablesamples. It seems like you've missed it, but feel free to read
about tablesample-method.sgml, that explains how this is achieved for
tablesamples.

If we want extensions to create a new copy handler, I think
something like pg_copy_hander should be necessary.

A catalog is not necessary, that's the point, because it can be
replaced by a scan of pg_proc with the function name defined in a COPY
query (be it through a FORMAT, or different option in a DefElem).
An example of extension with tablesamples is contrib/tsm_system_rows/,
that just uses a function returning a tsm_handler:
CREATE FUNCTION system_rows(internal)
RETURNS tsm_handler
AS 'MODULE_PATHNAME', 'tsm_system_rows_handler'
LANGUAGE C STRICT;

Then SELECT queries rely on the contents of the TABLESAMPLE clause to
find the set of callbacks it should use by calling the function.

+/* Routines for a COPY HANDLER implementation. */
+typedef struct CopyRoutine
+{

FWIW, I find weird the concept of having one handler for both COPY
FROM and COPY TO as each one of them has callbacks that are mutually
exclusive to the other, but I'm OK if there is a consensus of only
one. So I'd suggest to use *two* NodeTags instead for a cleaner
split, meaning that we'd need two functions for each method. My point
is that a custom COPY handler could just define a COPY TO handler or a
COPY FROM handler, though it mostly comes down to a matter of taste
regarding how clean the error handling becomes if one tries to use a
set of callbacks with a COPY type (TO or FROM) not matching it.
--
Michael

#19Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Michael Paquier (#18)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Fri, Dec 8, 2023 at 2:17 PM Michael Paquier <michael@paquier.xyz> wrote:

On Fri, Dec 08, 2023 at 10:32:27AM +0800, Junwang Zhao wrote:

I can see FDW related utility commands but no TABLESAMPLE related,
and there is a pg_foreign_data_wrapper system catalog which has
a *fdwhandler* field.

+ */ +CATALOG(pg_copy_handler,4551,CopyHandlerRelationId)

Using a catalog is an over-engineered design. Others have provided
hints about that upthread, but it would be enough to have one or two
handler types that are wrapped around one or two SQL *functions*, like
tablesamples. It seems like you've missed it, but feel free to read
about tablesample-method.sgml, that explains how this is achieved for
tablesamples.

Agreed. My previous example of FDW was not a good one, I missed something.

If we want extensions to create a new copy handler, I think
something like pg_copy_hander should be necessary.

A catalog is not necessary, that's the point, because it can be
replaced by a scan of pg_proc with the function name defined in a COPY
query (be it through a FORMAT, or different option in a DefElem).
An example of extension with tablesamples is contrib/tsm_system_rows/,
that just uses a function returning a tsm_handler:
CREATE FUNCTION system_rows(internal)
RETURNS tsm_handler
AS 'MODULE_PATHNAME', 'tsm_system_rows_handler'
LANGUAGE C STRICT;

Then SELECT queries rely on the contents of the TABLESAMPLE clause to
find the set of callbacks it should use by calling the function.

+/* Routines for a COPY HANDLER implementation. */
+typedef struct CopyRoutine
+{

FWIW, I find weird the concept of having one handler for both COPY
FROM and COPY TO as each one of them has callbacks that are mutually
exclusive to the other, but I'm OK if there is a consensus of only
one. So I'd suggest to use *two* NodeTags instead for a cleaner
split, meaning that we'd need two functions for each method. My point
is that a custom COPY handler could just define a COPY TO handler or a
COPY FROM handler, though it mostly comes down to a matter of taste
regarding how clean the error handling becomes if one tries to use a
set of callbacks with a COPY type (TO or FROM) not matching it.

I tend to agree to have separate two functions for each method. But
given we implement it in tablesample-way, I think we need to make it
clear how to call one of the two functions depending on COPY TO and
FROM.

IIUC in tablesamples cases, we scan pg_proc to find the handler
function like system_rows(internal) by the method name specified in
the query. On the other hand, in COPY cases, the queries would be
going to be like:

COPY tab TO stdout WITH (format = 'arrow');
and
COPY tab FROM stdin WITH (format = 'arrow');

So a custom COPY extension would not be able to define SQL functions
just like arrow(internal) for example. We might need to define a rule
like the function returning copy_in/out_handler must be defined as
<method name>_to(internal) and <method_name>_from(internal).

Regards,

--
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com

#20Michael Paquier
michael@paquier.xyz
In reply to: Masahiko Sawada (#19)
Re: Make COPY format extendable: Extract COPY TO format implementations

On Fri, Dec 08, 2023 at 03:42:06PM +0900, Masahiko Sawada wrote:

So a custom COPY extension would not be able to define SQL functions
just like arrow(internal) for example. We might need to define a rule
like the function returning copy_in/out_handler must be defined as
<method name>_to(internal) and <method_name>_from(internal).

Yeah, I was wondering if there was a trick to avoid the input internal
argument conflict, but cannot recall something elegant on the top of
my mind. Anyway, I'd be OK with any approach as long as it plays
nicely with the query integration, and that's FORMAT's DefElem with
its string value to do the function lookups.
--
Michael

#21Hayato Kuroda (Fujitsu)
kuroda.hayato@fujitsu.com
In reply to: Junwang Zhao (#17)
#22Junwang Zhao
zhjwpku@gmail.com
In reply to: Hayato Kuroda (Fujitsu) (#21)
#23Hannu Krosing
hannu@tm.ee
In reply to: Junwang Zhao (#22)
#24Sutou Kouhei
kou@clear-code.com
In reply to: Hayato Kuroda (Fujitsu) (#21)
#25Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#19)
#26Sutou Kouhei
kou@clear-code.com
In reply to: Hannu Krosing (#23)
#27Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#24)
#28Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#24)
#29Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#25)
#30Michael Paquier
michael@paquier.xyz
In reply to: Masahiko Sawada (#29)
#31Junwang Zhao
zhjwpku@gmail.com
In reply to: Hannu Krosing (#23)
#32Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Michael Paquier (#30)
#33Junwang Zhao
zhjwpku@gmail.com
In reply to: Masahiko Sawada (#32)
#34Hayato Kuroda (Fujitsu)
kuroda.hayato@fujitsu.com
In reply to: Sutou Kouhei (#24)
#35Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Junwang Zhao (#33)
#36Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#29)
#37Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#36)
#38Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#37)
#39Sutou Kouhei
kou@clear-code.com
In reply to: Hayato Kuroda (Fujitsu) (#34)
#40Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#38)
#41Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#38)
#42Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#40)
#43Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#42)
#44Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#32)
#45Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#44)
#46Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Michael Paquier (#45)
#47Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#44)
#48Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#44)
#49Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#45)
#50Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#47)
#51Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#48)
#52Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#49)
#53Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#52)
#54Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#53)
#55Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#54)
#56Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#55)
#57Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#51)
#58Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#57)
#59Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#56)
#60Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#55)
#61Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#60)
#62Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#59)
#63Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#62)
#64Andrew Dunstan
andrew@dunslane.net
In reply to: Michael Paquier (#63)
#65Sutou Kouhei
kou@clear-code.com
In reply to: Andrew Dunstan (#64)
#66Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#62)
#67jian he
jian.universality@gmail.com
In reply to: Sutou Kouhei (#65)
#68Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#65)
#69Michael Paquier
michael@paquier.xyz
In reply to: jian he (#67)
#70Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#65)
#71Michael Paquier
michael@paquier.xyz
In reply to: Masahiko Sawada (#70)
#72Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Michael Paquier (#71)
#73Sutou Kouhei
kou@clear-code.com
In reply to: jian he (#67)
#74Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#68)
#75Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#70)
#76Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#74)
#77Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#75)
#78Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#77)
#79Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#78)
#80Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#76)
#81Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#79)
#82Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#81)
#83Junwang Zhao
zhjwpku@gmail.com
In reply to: Junwang Zhao (#82)
#84Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Junwang Zhao (#82)
#85Junwang Zhao
zhjwpku@gmail.com
In reply to: Masahiko Sawada (#84)
#86Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Junwang Zhao (#85)
#87Junwang Zhao
zhjwpku@gmail.com
In reply to: Masahiko Sawada (#86)
#88Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#83)
#89Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#88)
#90Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#87)
#91Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#90)
#92Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#91)
#93Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#92)
#94Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#93)
#95Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#94)
#96Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#95)
#97Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#96)
#98Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#97)
#99Junwang Zhao
zhjwpku@gmail.com
In reply to: Michael Paquier (#98)
#100Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#98)
#101Michael Paquier
michael@paquier.xyz
In reply to: Junwang Zhao (#99)
#102Junwang Zhao
zhjwpku@gmail.com
In reply to: Michael Paquier (#101)
#103Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#100)
#104Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#103)
#105Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#104)
#106Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#104)
#107Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#105)
#108Junwang Zhao
zhjwpku@gmail.com
In reply to: Michael Paquier (#107)
#109Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#107)
#110Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#108)
#111Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#109)
#112Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#111)
#113Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#112)
#114Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#113)
#115Andres Freund
andres@anarazel.de
In reply to: Michael Paquier (#113)
#116Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#114)
#117Michael Paquier
michael@paquier.xyz
In reply to: Andres Freund (#115)
#118Andres Freund
andres@anarazel.de
In reply to: Michael Paquier (#117)
#119Michael Paquier
michael@paquier.xyz
In reply to: Andres Freund (#118)
#120Andres Freund
andres@anarazel.de
In reply to: Michael Paquier (#119)
#121Michael Paquier
michael@paquier.xyz
In reply to: Andres Freund (#120)
#122Andres Freund
andres@anarazel.de
In reply to: Michael Paquier (#121)
#123Michael Paquier
michael@paquier.xyz
In reply to: Andres Freund (#122)
#124Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#98)
#125Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#123)
#126Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#123)
#127Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#125)
#128Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#126)
#129Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#128)
#130Andres Freund
andres@anarazel.de
In reply to: Michael Paquier (#126)
#131Michael Paquier
michael@paquier.xyz
In reply to: Andres Freund (#130)
#132Sutou Kouhei
kou@clear-code.com
In reply to: Andres Freund (#130)
#133Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#132)
#134Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#133)
#135Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#134)
#136Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#135)
#137Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#132)
#138jian he
jian.universality@gmail.com
In reply to: Sutou Kouhei (#136)
#139Sutou Kouhei
kou@clear-code.com
In reply to: jian he (#138)
#140Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#136)
#141Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#140)
#142Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#141)
#143Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#141)
#144Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#142)
#145Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#144)
#146Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#145)
#147Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#146)
#148Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#147)
#149Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#148)
#150Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#149)
#151jian he
jian.universality@gmail.com
In reply to: Sutou Kouhei (#150)
#152Sutou Kouhei
kou@clear-code.com
In reply to: jian he (#151)
#153jian he
jian.universality@gmail.com
In reply to: Sutou Kouhei (#152)
#154Sutou Kouhei
kou@clear-code.com
In reply to: jian he (#153)
#155Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#150)
#156Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#155)
#157Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Sutou Kouhei (#156)
#158Li, Yong
yoli@ebay.com
In reply to: Tomas Vondra (#157)
#159Sutou Kouhei
kou@clear-code.com
In reply to: Tomas Vondra (#157)
#160Sutou Kouhei
kou@clear-code.com
In reply to: Li, Yong (#158)
#161Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Sutou Kouhei (#159)
#162Sutou Kouhei
kou@clear-code.com
In reply to: Tomas Vondra (#161)
#163Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#162)
#164Li, Yong
yoli@ebay.com
In reply to: Sutou Kouhei (#163)
#165Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#162)
#166Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Sutou Kouhei (#163)
#167Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#165)
#168Sutou Kouhei
kou@clear-code.com
In reply to: Tomas Vondra (#166)
#169Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Sutou Kouhei (#168)
#170Sutou Kouhei
kou@clear-code.com
In reply to: Tomas Vondra (#169)
#171Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#170)
#172Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#171)
#173Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#172)
#174Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#173)
#175Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#174)
#176Michael Paquier
michael@paquier.xyz
In reply to: Masahiko Sawada (#174)
#177Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Michael Paquier (#176)
#178Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Masahiko Sawada (#177)
#179Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#178)
#180Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#179)
#181Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#180)
#182Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Masahiko Sawada (#181)
#183Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#182)
#184Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#183)
#185Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Masahiko Sawada (#184)
#186Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#185)
#187Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Masahiko Sawada (#185)
#188Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Alvaro Herrera (#187)
#189Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#186)
#190Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#189)
#191Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#190)
#192Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#190)
#193Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#192)
#194Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#191)
#195Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#194)
#196Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#195)
#197Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#196)
#198Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#197)
#199Sutou Kouhei
kou@clear-code.com
In reply to: Junwang Zhao (#198)
#200Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#199)
#201Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#200)
#202Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#201)
#203Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#202)
#204Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#203)
#205Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#204)
#206Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#205)
#207Vladlen Popolitov
v.popolitov@postgrespro.ru
In reply to: Sutou Kouhei (#206)
#208Sutou Kouhei
kou@clear-code.com
In reply to: Vladlen Popolitov (#207)
#209Vladlen Popolitov
v.popolitov@postgrespro.ru
In reply to: Sutou Kouhei (#208)
#210Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Vladlen Popolitov (#209)
#211Vladlen Popolitov
v.popolitov@postgrespro.ru
In reply to: Masahiko Sawada (#210)
#212Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#206)
#213Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Vladlen Popolitov (#211)
#214Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Michael Paquier (#212)
#215Sutou Kouhei
kou@clear-code.com
In reply to: Vladlen Popolitov (#209)
#216Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#210)
#217Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Vladlen Popolitov (#207)
#218Vladlen Popolitov
v.popolitov@postgrespro.ru
In reply to: Alvaro Herrera (#217)
#219Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Alvaro Herrera (#217)
#220Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Masahiko Sawada (#219)
#221Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#216)
#222Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#221)
#223Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#214)
#224Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#223)
#225Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#224)
#226Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#225)
#227Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#226)
#228Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#227)
#229Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#228)
#230Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#229)
#231Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#230)
#232Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#231)
#233Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#232)
#234Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#233)
#235Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#234)
#236Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#235)
#237Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#236)
#238Tom Lane
tgl@sss.pgh.pa.us
In reply to: Junwang Zhao (#237)
#239Sutou Kouhei
kou@clear-code.com
In reply to: Tom Lane (#238)
#240Junwang Zhao
zhjwpku@gmail.com
In reply to: Sutou Kouhei (#239)
#241Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#239)
#242Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#241)
#243Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#242)
#244Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#243)
#245David G. Johnston
david.g.johnston@gmail.com
In reply to: Sutou Kouhei (#244)
#246Sutou Kouhei
kou@clear-code.com
In reply to: David G. Johnston (#245)
#247David G. Johnston
david.g.johnston@gmail.com
In reply to: Sutou Kouhei (#244)
#248Masahiko Sawada
sawada.mshk@gmail.com
In reply to: David G. Johnston (#247)
#249David G. Johnston
david.g.johnston@gmail.com
In reply to: Masahiko Sawada (#248)
#250David G. Johnston
david.g.johnston@gmail.com
In reply to: David G. Johnston (#249)
#251Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#246)
#252Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#246)
#253Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#251)
#254Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#253)
#255David G. Johnston
david.g.johnston@gmail.com
In reply to: Masahiko Sawada (#254)
#256Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#254)
#257David G. Johnston
david.g.johnston@gmail.com
In reply to: Sutou Kouhei (#256)
#258David G. Johnston
david.g.johnston@gmail.com
In reply to: Sutou Kouhei (#253)
#259Sutou Kouhei
kou@clear-code.com
In reply to: David G. Johnston (#258)
#260David G. Johnston
david.g.johnston@gmail.com
In reply to: Sutou Kouhei (#253)
#261Masahiko Sawada
sawada.mshk@gmail.com
In reply to: David G. Johnston (#258)
#262Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#256)
#263David G. Johnston
david.g.johnston@gmail.com
In reply to: Masahiko Sawada (#261)
#264Sutou Kouhei
kou@clear-code.com
In reply to: David G. Johnston (#260)
#265Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#262)
#266jian he
jian.universality@gmail.com
In reply to: Sutou Kouhei (#253)
#267David G. Johnston
david.g.johnston@gmail.com
In reply to: jian he (#266)
#268Sutou Kouhei
kou@clear-code.com
In reply to: jian he (#266)
#269Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#265)
#270Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#269)
#271Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#270)
#272Michael Paquier
michael@paquier.xyz
In reply to: Masahiko Sawada (#271)
#273Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Michael Paquier (#272)
#274Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#271)
#275Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#273)
#276Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#274)
#277Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#276)
#278David G. Johnston
david.g.johnston@gmail.com
In reply to: Masahiko Sawada (#271)
#279Masahiko Sawada
sawada.mshk@gmail.com
In reply to: David G. Johnston (#278)
#280Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#277)
#281Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#280)
#282David G. Johnston
david.g.johnston@gmail.com
In reply to: Masahiko Sawada (#279)
#283Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#281)
#284Masahiko Sawada
sawada.mshk@gmail.com
In reply to: David G. Johnston (#282)
#285David G. Johnston
david.g.johnston@gmail.com
In reply to: Masahiko Sawada (#284)
#286Masahiko Sawada
sawada.mshk@gmail.com
In reply to: David G. Johnston (#285)
#287David G. Johnston
david.g.johnston@gmail.com
In reply to: Masahiko Sawada (#286)
#288Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#283)
#289Sutou Kouhei
kou@clear-code.com
In reply to: David G. Johnston (#287)
#290Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#289)
#291Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#288)
#292Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#290)
#293Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#291)
#294Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#292)
#295Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Michael Paquier (#294)
#296Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#295)
#297Michael Paquier
michael@paquier.xyz
In reply to: Sutou Kouhei (#296)
#298Sutou Kouhei
kou@clear-code.com
In reply to: Michael Paquier (#297)
#299Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#298)
#300Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#299)
#301Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#300)
#302Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#301)
#303Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#302)
#304Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#303)
#305Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#304)
#306Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Masahiko Sawada (#305)
#307Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#306)
#308Sutou Kouhei
kou@clear-code.com
In reply to: Sutou Kouhei (#307)
#309Andres Freund
andres@anarazel.de
In reply to: Masahiko Sawada (#306)
#310Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Andres Freund (#309)
#311Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#308)
#312Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#310)
#313Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#311)
#314Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#313)
#315Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Masahiko Sawada (#314)
#316Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#315)
#317Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#316)
#318Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#317)
#319Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#318)
#320Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#319)
#321Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#320)
#322Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#321)
#323Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#322)
#324Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#323)
#325Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#324)
#326Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#325)
#327Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#326)
#328Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#327)
#329Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#328)
#330Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Masahiko Sawada (#329)
#331Sutou Kouhei
kou@clear-code.com
In reply to: Masahiko Sawada (#330)
#332Tomas Vondra
tomas.vondra@2ndquadrant.com
In reply to: Masahiko Sawada (#330)
#333Sutou Kouhei
kou@clear-code.com
In reply to: Tomas Vondra (#332)
#334Masahiko Sawada
sawada.mshk@gmail.com
In reply to: Sutou Kouhei (#333)