Refactor CopyOneRowTo
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 16 Aug 2024 10:48:10 +0000 (13:48 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 16 Aug 2024 10:48:10 +0000 (13:48 +0300)
The handling of binary and text formats are quite different here, so
it's more clear to check for the format first and have two separate
loops.

Author: jian he <jian.universality@gmail.com>
Reviewed-by: Ilia Evdokimov, Junwang Zhao
Discussion: https://www.postgresql.org/message-id/CACJufxFzHCeFBQF0M%2BSgk_NwknWuQ4oU7tS1isVeBrbhcKOHkg@mail.gmail.com

src/backend/commands/copyto.c

index eb1d3d8fbb5a056e37ac0ec794dc62a08d26f849..91de442f4341a614d175ff5b599839ecbcc9e7c8 100644 (file)
@@ -902,11 +902,8 @@ DoCopyTo(CopyToState cstate)
 static void
 CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
 {
-       bool            need_delim = false;
        FmgrInfo   *out_functions = cstate->out_functions;
        MemoryContext oldcontext;
-       ListCell   *cur;
-       char       *string;
 
        MemoryContextReset(cstate->rowcontext);
        oldcontext = MemoryContextSwitchTo(cstate->rowcontext);
@@ -920,29 +917,23 @@ 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];
+               bool            need_delim = false;
 
-               if (!cstate->opts.binary)
+               foreach_int(attnum, cstate->attnumlist)
                {
+                       Datum           value = slot->tts_values[attnum - 1];
+                       bool            isnull = slot->tts_isnull[attnum - 1];
+                       char       *string;
+
                        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);
@@ -952,10 +943,20 @@ CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
                                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
                        {
-                               bytea      *outputbytes;
-
                                outputbytes = SendFunctionCall(&out_functions[attnum - 1],
                                                                                           value);
                                CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ);