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 <[email protected]>
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