original CopyOneRowTo: https://git.postgresql.org/cgit/postgresql.git/tree/src/backend/commands/copyto.c#n922 I change it to: ----------------------- if (!cstate->opts.binary) { foreach_int(attnum, cstate->attnumlist) { Datum value = slot->tts_values[attnum - 1]; bool isnull = slot->tts_isnull[attnum - 1];
if (need_delim) CopySendChar(cstate, cstate->opts.delim[0]); need_delim = true; if (isnull) CopySendString(cstate, cstate->opts.null_print_client); else { string = OutputFunctionCall(&out_functions[attnum - 1], value); if (cstate->opts.csv_mode) CopyAttributeOutCSV(cstate, string, cstate->opts.force_quote_flags[attnum - 1]); else CopyAttributeOutText(cstate, string); } } } else { foreach_int(attnum, cstate->attnumlist) { Datum value = slot->tts_values[attnum - 1]; bool isnull = slot->tts_isnull[attnum - 1]; bytea *outputbytes; if (isnull) CopySendInt32(cstate, -1); else { outputbytes = SendFunctionCall(&out_functions[attnum - 1], value); CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ); CopySendData(cstate, VARDATA(outputbytes), VARSIZE(outputbytes) - VARHDRSZ); } } } overall less "if else" logic, also copy format don't change during copy, we don't need to check binary or nor for each datum value.
From eff237930ddc8727044aff29e5b01499f1b14c77 Mon Sep 17 00:00:00 2001 From: jian he <jian.universal...@gmail.com> Date: Fri, 5 Jul 2024 00:19:04 +0800 Subject: [PATCH v1 1/1] refactor CopyOneRowTo --- src/backend/commands/copyto.c | 44 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c index ae8b2e36..ffafe4c7 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -904,7 +904,6 @@ CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot) bool need_delim = false; FmgrInfo *out_functions = cstate->out_functions; MemoryContext oldcontext; - ListCell *cur; char *string; MemoryContextReset(cstate->rowcontext); @@ -919,30 +918,21 @@ CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot) /* Make sure the tuple is fully deconstructed */ slot_getallattrs(slot); - foreach(cur, cstate->attnumlist) + if (!cstate->opts.binary) { - int attnum = lfirst_int(cur); - Datum value = slot->tts_values[attnum - 1]; - bool isnull = slot->tts_isnull[attnum - 1]; - - if (!cstate->opts.binary) + foreach_int(attnum, cstate->attnumlist) { + Datum value = slot->tts_values[attnum - 1]; + bool isnull = slot->tts_isnull[attnum - 1]; + if (need_delim) CopySendChar(cstate, cstate->opts.delim[0]); need_delim = true; - } - if (isnull) - { - if (!cstate->opts.binary) + if (isnull) CopySendString(cstate, cstate->opts.null_print_client); else - CopySendInt32(cstate, -1); - } - else - { - if (!cstate->opts.binary) - { + { string = OutputFunctionCall(&out_functions[attnum - 1], value); if (cstate->opts.csv_mode) @@ -951,15 +941,25 @@ CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot) else CopyAttributeOutText(cstate, string); } - else - { - bytea *outputbytes; + } + } + else + { + foreach_int(attnum, cstate->attnumlist) + { + Datum value = slot->tts_values[attnum - 1]; + bool isnull = slot->tts_isnull[attnum - 1]; + bytea *outputbytes; + if (isnull) + CopySendInt32(cstate, -1); + else + { outputbytes = SendFunctionCall(&out_functions[attnum - 1], - value); + value); CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ); CopySendData(cstate, VARDATA(outputbytes), - VARSIZE(outputbytes) - VARHDRSZ); + VARSIZE(outputbytes) - VARHDRSZ); } } } base-commit: dec9d4acdb7d758c3cbe989ad80cf0367f4e166d -- 2.34.1