This is an automated email from the ASF dual-hosted git repository.

kou pushed a commit to branch main
in repository 
https://gitbox.apache.org/repos/asf/arrow-flight-sql-postgresql.git


The following commit(s) were added to refs/heads/main by this push:
     new 574d7a0  Add benchmark for bulk ingestion (#170)
574d7a0 is described below

commit 574d7a058a1f5927e2f6187e5ed4d4a3b7da1b21
Author: Sutou Kouhei <[email protected]>
AuthorDate: Fri Nov 17 11:48:03 2023 +0900

    Add benchmark for bulk ingestion (#170)
    
    Closes GH-169
    
    Apache Arrow Flight SQL is slow because the current implementation
    inserts records one by one.
    
    We will be able to improve performance by using a new bulk ingestion
    Flight SQL command.
    
    See also: https://github.com/apache/arrow/issues/38255
---
 benchmark/graph.rb                                 |  22 +-
 benchmark/insert-copy.cc                           | 152 ++++++++
 benchmark/{select.rb => insert-flight-sql.rb}      |  21 +-
 benchmark/insert.cc                                | 139 ++++++++
 benchmark/integer/README.md                        |  36 +-
 benchmark/integer/insert.csv                       |  10 +
 .../{string/result.svg => integer/insert.svg}      | 385 +++++++++++----------
 benchmark/integer/result.csv                       |  10 -
 benchmark/integer/select.csv                       |  10 +
 benchmark/integer/{result.svg => select.svg}       | 112 +++---
 benchmark/markdown.rb                              |  74 ++--
 benchmark/meson.build                              |   5 +-
 benchmark/run.sh                                   |  37 +-
 benchmark/{copy.c => select-copy.c}                |   0
 benchmark/{select.rb => select-flight-sql.rb}      |   0
 benchmark/string/README.md                         |  36 +-
 benchmark/string/insert.csv                        |  10 +
 .../{integer/result.svg => string/insert.svg}      | 285 +++++++--------
 benchmark/string/result.csv                        |  10 -
 benchmark/string/select.csv                        |  10 +
 benchmark/string/{result.svg => select.svg}        | 182 ++++------
 dev/release/rat_exclude_files.txt                  |   4 +-
 src/afs.cc                                         |  18 +-
 23 files changed, 976 insertions(+), 592 deletions(-)

diff --git a/benchmark/graph.rb b/benchmark/graph.rb
index 9d6f3cd..d2f40e7 100755
--- a/benchmark/graph.rb
+++ b/benchmark/graph.rb
@@ -26,14 +26,20 @@ benchmarks = [
   "integer",
   "string",
 ]
+types = [
+  "insert",
+  "select",
+]
 benchmarks.each do |benchmark|
   base_dir = File.join(__dir__, benchmark)
-  data = CSV.read(File.join(base_dir, "result.csv"),
-                  headers: true,
-                  converters: :all)
-  plotter = Charty.bar_plot(data: data,
-                            x: "N records",
-                            y: "Elapsed time (sec)",
-                            color: "Approach")
-  plotter.save(File.join(base_dir, "result.svg"))
+  types.each do |type|
+    data = CSV.read(File.join(base_dir, "#{type}.csv"),
+                    headers: true,
+                    converters: :all)
+    plotter = Charty.bar_plot(data: data,
+                              x: "N records",
+                              y: "Elapsed time (sec)",
+                              color: "Approach")
+    plotter.save(File.join(base_dir, "#{type}.svg"))
+  end
 end
diff --git a/benchmark/insert-copy.cc b/benchmark/insert-copy.cc
new file mode 100644
index 0000000..d2f8165
--- /dev/null
+++ b/benchmark/insert-copy.cc
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <chrono>
+#include <cstdlib>
+#include <iostream>
+#include <vector>
+
+#include <libpq-fe.h>
+
+class ConnectionFinisher {
+   public:
+       ConnectionFinisher(PGconn* connection) : connection_(connection) {}
+       ~ConnectionFinisher() { PQfinish(connection_); }
+
+   private:
+       PGconn* connection_;
+};
+
+class ResultClearner {
+   public:
+       ResultClearner(PGresult* result) : result_(result) {}
+       ~ResultClearner() { PQclear(result_); }
+
+   private:
+       PGresult* result_;
+};
+
+int
+main(int argc, char** argv)
+{
+       std::string connectionString;
+       if (!std::getenv("PGDATABASE"))
+       {
+               connectionString += "dbname=afs_benchmark";
+       }
+       auto connection = PQconnectdb(connectionString.c_str());
+       ConnectionFinisher connectionFinisher(connection);
+       if (PQstatus(connection) != CONNECTION_OK)
+       {
+               std::cerr << "failed to connect: " << 
PQerrorMessage(connection) << std::endl;
+               return EXIT_FAILURE;
+       }
+
+       {
+               auto result = PQexec(connection, "DROP TABLE IF EXISTS 
data_insert");
+               ResultClearner resultClearner(result);
+               if (PQresultStatus(result) != PGRES_COMMAND_OK)
+               {
+                       std::cerr << "failed to drop: " << 
PQerrorMessage(connection) << std::endl;
+                       return EXIT_FAILURE;
+               }
+       }
+
+       {
+               auto result = PQexec(connection, "CREATE TABLE data_insert 
(LIKE data)");
+               ResultClearner resultClearner(result);
+               if (PQresultStatus(result) != PGRES_COMMAND_OK)
+               {
+                       std::cerr << "failed to create: " << 
PQerrorMessage(connection) << std::endl;
+                       return EXIT_FAILURE;
+               }
+       }
+
+       std::vector<std::string> buffers;
+       {
+               auto result = PQexec(connection, "COPY data TO STDOUT (FORMAT 
binary)");
+               ResultClearner resultClearner(result);
+               if (PQresultStatus(result) != PGRES_COPY_OUT)
+               {
+                       std::cerr << "failed to copy to: " << 
PQerrorMessage(connection) << std::endl;
+                       return EXIT_FAILURE;
+               }
+               while (true)
+               {
+                       char* data;
+                       auto size = PQgetCopyData(connection, &data, 0);
+                       if (size == -1)
+                       {
+                               break;
+                       }
+                       if (size == -2)
+                       {
+                               std::cerr << "failed to read copy data: " << 
PQerrorMessage(connection)
+                                                 << std::endl;
+                               return EXIT_FAILURE;
+                       }
+                       buffers.emplace_back(data, size);
+                       free(data);
+               }
+       }
+       auto before = std::chrono::steady_clock::now();
+       {
+               auto result = PQexec(connection, "COPY data_insert FROM STDOUT 
(FORMAT binary)");
+               ResultClearner resultClearner(result);
+               if (PQresultStatus(result) != PGRES_COPY_IN)
+               {
+                       std::cerr << "failed to copy from: " << 
PQerrorMessage(connection)
+                                         << std::endl;
+                       return EXIT_FAILURE;
+               }
+               for (const auto& buffer : buffers)
+               {
+                       auto copyDataResult = PQputCopyData(connection, 
buffer.data(), buffer.size());
+                       if (copyDataResult == -1)
+                       {
+                               std::cerr << "failed to put copy data: " << 
PQerrorMessage(connection)
+                                                 << std::endl;
+                               return EXIT_FAILURE;
+                       }
+               }
+               auto copyEndResult = PQputCopyEnd(connection, nullptr);
+               if (copyEndResult == -1)
+               {
+                       std::cerr << "failed to end copy data: " << 
PQerrorMessage(connection)
+                                         << std::endl;
+                       return EXIT_FAILURE;
+               }
+       }
+       {
+               auto result = PQgetResult(connection);
+               ResultClearner resultClearner(result);
+               if (PQresultStatus(result) != PGRES_COMMAND_OK)
+               {
+                       std::cerr << "failed to copy from: " << 
PQerrorMessage(connection)
+                                         << std::endl;
+                       return EXIT_FAILURE;
+               }
+       }
+       auto elapsedTime = 
std::chrono::duration_cast<std::chrono::milliseconds>(
+                                                  
std::chrono::steady_clock::now() - before)
+                              .count();
+       printf("%.3f\n", elapsedTime / 1000.0);
+
+       return EXIT_SUCCESS;
+}
diff --git a/benchmark/select.rb b/benchmark/insert-flight-sql.rb
similarity index 73%
copy from benchmark/select.rb
copy to benchmark/insert-flight-sql.rb
index 07f3550..e8d291a 100755
--- a/benchmark/select.rb
+++ b/benchmark/insert-flight-sql.rb
@@ -30,10 +30,25 @@ client.authenticate_basic(ENV["PGUSER"] || ENV["USER"],
                           call_options)
 sql_client = ArrowFlightSQL::Client.new(client)
 
-before = Time.now
+sql_client.execute_update("DROP TABLE IF EXISTS data_insert", call_options)
+sql_client.execute_update("CREATE TABLE data_insert (LIKE data)", call_options)
+
 info = sql_client.execute("SELECT * FROM data", call_options)
 endpoint = info.endpoints.first
 reader = sql_client.do_get(endpoint.ticket, call_options)
-_table = reader.read_all
-# p _table
+record_batches = []
+loop do
+  record_batch = reader.read_next
+  break if record_batch.nil?
+  record_batches << record_batch.data
+end
+
+before = Time.now
+sql_client.prepare("INSERT INTO data_insert VALUES ($1)",
+                   call_options) do |statement|
+  record_batches.each do |record_batch|
+    statement.record_batch = record_batch
+    statement.execute_update(call_options)
+  end
+end
 puts("%.3f" % (Time.now - before))
diff --git a/benchmark/insert.cc b/benchmark/insert.cc
new file mode 100644
index 0000000..7eb58f5
--- /dev/null
+++ b/benchmark/insert.cc
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <chrono>
+#include <cstdlib>
+#include <iostream>
+
+#include <libpq-fe.h>
+
+#include <catalog/pg_type_d.h>
+
+class ConnectionFinisher {
+   public:
+       ConnectionFinisher(PGconn* connection) : connection_(connection) {}
+       ~ConnectionFinisher() { PQfinish(connection_); }
+
+   private:
+       PGconn* connection_;
+};
+
+class ResultClearner {
+   public:
+       ResultClearner(PGresult* result) : result_(result) {}
+       ~ResultClearner() { PQclear(result_); }
+
+   private:
+       PGresult* result_;
+};
+
+int
+main(int argc, char** argv)
+{
+       std::string connectionString;
+       if (!std::getenv("PGDATABASE"))
+       {
+               connectionString += "dbname=afs_benchmark";
+       }
+       auto connection = PQconnectdb(connectionString.c_str());
+       ConnectionFinisher connectionFinisher(connection);
+       if (PQstatus(connection) != CONNECTION_OK)
+       {
+               std::cerr << "failed to connect: " << 
PQerrorMessage(connection) << std::endl;
+               return EXIT_FAILURE;
+       }
+
+       {
+               auto result = PQexec(connection, "DROP TABLE IF EXISTS 
data_insert");
+               ResultClearner resultClearner(result);
+               if (PQresultStatus(result) != PGRES_COMMAND_OK)
+               {
+                       std::cerr << "failed to drop: " << 
PQerrorMessage(connection) << std::endl;
+                       return EXIT_FAILURE;
+               }
+       }
+
+       {
+               auto result = PQexec(connection, "CREATE TABLE data_insert 
(LIKE data)");
+               ResultClearner resultClearner(result);
+               if (PQresultStatus(result) != PGRES_COMMAND_OK)
+               {
+                       std::cerr << "failed to create: " << 
PQerrorMessage(connection) << std::endl;
+                       return EXIT_FAILURE;
+               }
+       }
+
+       std::string insert = "INSERT INTO data_insert VALUES ";
+       {
+               auto result = PQexec(connection, "SELECT * FROM data");
+               ResultClearner resultClearner(result);
+               if (PQresultStatus(result) != PGRES_TUPLES_OK)
+               {
+                       std::cerr << "failed to select: " << 
PQerrorMessage(connection) << std::endl;
+                       return EXIT_FAILURE;
+               }
+               auto nTuples = PQntuples(result);
+               auto nFields = PQnfields(result);
+               for (int iTuple = 0; iTuple < nTuples; iTuple++)
+               {
+                       if (iTuple > 0)
+                       {
+                               insert += ", ";
+                       }
+                       for (int iField = 0; iField < nFields; iField++)
+                       {
+                               if (PQgetisnull(result, iTuple, iField))
+                               {
+                                       insert += "(null)";
+                               }
+                               else
+                               {
+                                       insert += "(";
+                                       auto type = PQftype(result, iField);
+                                       if (type == TEXTOID)
+                                       {
+                                               insert += "'";
+                                       }
+                                       insert += PQgetvalue(result, iTuple, 
iField);
+                                       if (type == TEXTOID)
+                                       {
+                                               insert += "'";
+                                       }
+                                       insert += ")";
+                               }
+                       }
+               }
+       }
+       auto before = std::chrono::steady_clock::now();
+       {
+               auto result = PQexec(connection, insert.c_str());
+               ResultClearner resultClearner(result);
+               if (PQresultStatus(result) != PGRES_COMMAND_OK)
+               {
+                       std::cerr << "failed to insert: " << 
PQerrorMessage(connection) << std::endl;
+                       return EXIT_FAILURE;
+               }
+       }
+       auto elapsedTime = 
std::chrono::duration_cast<std::chrono::milliseconds>(
+                                                  
std::chrono::steady_clock::now() - before)
+                              .count();
+       printf("%.3f\n", elapsedTime / 1000.0);
+
+       return EXIT_SUCCESS;
+}
diff --git a/benchmark/integer/README.md b/benchmark/integer/README.md
index 3777f78..60e7a7c 100644
--- a/benchmark/integer/README.md
+++ b/benchmark/integer/README.md
@@ -23,7 +23,7 @@
 
 See the [README.md in the parent directory](../README.md).
 
-## Result
+## Environment
 
 Here is a benchmark result on the following environment:
 
@@ -38,22 +38,48 @@ Here is a benchmark result on the following environment:
   0.2.0 (not released yet)
   14df9b5fe61eda2d71bdfbf67c61a227741f616c
 
-![Graph](result.svg)
+## Results
+
+### `SELECT`
+
+![Graph](select.svg)
 
 100K records:
 
 | Apache Arrow Flight SQL | `SELECT` | `COPY` |
 | ----------------------- | -------- | ------ |
-| 0.015                   | 0.015    | 0.012  |
+| 0.014                   | 0.015    | 0.011  |
 
 1M records:
 
 | Apache Arrow Flight SQL | `SELECT` | `COPY` |
 | ----------------------- | -------- | ------ |
-| 0.111                   | 0.148    | 0.114  |
+| 0.082                   | 0.145    | 0.110  |
 
 10M records:
 
 | Apache Arrow Flight SQL | `SELECT` | `COPY` |
 | ----------------------- | -------- | ------ |
-| 0.958                   | 1.502    | 1.162  |
+| 0.694                   | 1.486    | 1.142  |
+
+### `INSERT`
+
+![Graph](insert.svg)
+
+100K records:
+
+| Apache Arrow Flight SQL | `INSERT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 0.273                   | 0.121    | 0.020  |
+
+1M records:
+
+| Apache Arrow Flight SQL | `INSERT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 6.055                   | 2.232    | 0.345  |
+
+10M records:
+
+| Apache Arrow Flight SQL | `INSERT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 51.757                  | 31.390   | 7.832  |
diff --git a/benchmark/integer/insert.csv b/benchmark/integer/insert.csv
new file mode 100644
index 0000000..068c12c
--- /dev/null
+++ b/benchmark/integer/insert.csv
@@ -0,0 +1,10 @@
+Approach,N records,Elapsed time (sec)
+Apache Arrow Flight SQL,100000,0.273
+INSERT,100000,0.121
+COPY,100000,0.020
+Apache Arrow Flight SQL,1000000,6.055
+INSERT,1000000,2.232
+COPY,1000000,0.345
+Apache Arrow Flight SQL,10000000,51.757
+INSERT,10000000,31.390
+COPY,10000000,7.832
diff --git a/benchmark/string/result.svg b/benchmark/integer/insert.svg
similarity index 85%
copy from benchmark/string/result.svg
copy to benchmark/integer/insert.svg
index 590670f..edae65a 100644
--- a/benchmark/string/result.svg
+++ b/benchmark/integer/insert.svg
@@ -6,7 +6,7 @@
   <rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/"; 
xmlns:cc="http://creativecommons.org/ns#"; 
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";>
    <cc:Work>
     <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:date>2023-11-13T18:19:08.495288</dc:date>
+    <dc:date>2023-11-16T18:51:19.434953</dc:date>
     <dc:format>image/svg+xml</dc:format>
     <dc:creator>
      <cc:Agent>
@@ -40,18 +40,18 @@ z
    <g id="patch_3">
     <path d="M 69.82144 307.584 
 L 100.93056 307.584 
-L 100.93056 303.547511 
-L 69.82144 303.547511 
+L 100.93056 306.247193 
+L 69.82144 306.247193 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #1f77b4"/>
+" clip-path="url(#p81d22f9aab)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_4">
     <path d="M 188.86144 307.584 
 L 219.97056 307.584 
-L 219.97056 263.612031 
-L 188.86144 263.612031 
+L 219.97056 277.934306 
+L 188.86144 277.934306 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #1f77b4"/>
+" clip-path="url(#p81d22f9aab)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_5">
     <path d="M 307.90144 307.584 
@@ -59,66 +59,66 @@ L 339.01056 307.584
 L 339.01056 54.144 
 L 307.90144 54.144 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #1f77b4"/>
+" clip-path="url(#p81d22f9aab)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_6">
     <path d="M 101.56544 307.584 
 L 132.67456 307.584 
-L 132.67456 306.123993 
-L 101.56544 306.123993 
+L 132.67456 306.991496 
+L 101.56544 306.991496 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #ff7f0e"/>
+" clip-path="url(#p81d22f9aab)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_7">
     <path d="M 220.60544 307.584 
 L 251.71456 307.584 
-L 251.71456 294.272174 
-L 220.60544 294.272174 
+L 251.71456 296.654501 
+L 220.60544 296.654501 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #ff7f0e"/>
+" clip-path="url(#p81d22f9aab)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_8">
     <path d="M 339.64544 307.584 
 L 370.75456 307.584 
-L 370.75456 161.068026 
-L 339.64544 161.068026 
+L 370.75456 153.875678 
+L 339.64544 153.875678 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #ff7f0e"/>
+" clip-path="url(#p81d22f9aab)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_9">
     <path d="M 133.30944 307.584 
 L 164.41856 307.584 
-L 164.41856 306.123993 
-L 133.30944 306.123993 
+L 164.41856 307.486065 
+L 133.30944 307.486065 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #2ca02c"/>
+" clip-path="url(#p81d22f9aab)" style="fill: #2ca02c"/>
    </g>
    <g id="patch_10">
     <path d="M 252.34944 307.584 
 L 283.45856 307.584 
-L 283.45856 294.443939 
-L 252.34944 294.443939 
+L 283.45856 305.894629 
+L 252.34944 305.894629 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #2ca02c"/>
+" clip-path="url(#p81d22f9aab)" style="fill: #2ca02c"/>
    </g>
    <g id="patch_11">
     <path d="M 371.38944 307.584 
 L 402.49856 307.584 
-L 402.49856 166.736287 
-L 371.38944 166.736287 
+L 402.49856 269.232819 
+L 371.38944 269.232819 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #2ca02c"/>
+" clip-path="url(#p81d22f9aab)" style="fill: #2ca02c"/>
    </g>
    <g id="matplotlib.axis_1">
     <g id="xtick_1">
      <g id="line2d_1">
       <defs>
-       <path id="mc298820655" d="M 0 0 
+       <path id="m981c6d9a00" d="M 0 0 
 L 0 3.5 
 " style="stroke: #000000; stroke-width: 0.8"/>
       </defs>
       <g>
-       <use xlink:href="#mc298820655" x="117.12" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m981c6d9a00" x="117.12" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_1">
@@ -173,7 +173,7 @@ z
     <g id="xtick_2">
      <g id="line2d_2">
       <g>
-       <use xlink:href="#mc298820655" x="236.16" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m981c6d9a00" x="236.16" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_2">
@@ -192,7 +192,7 @@ z
     <g id="xtick_3">
      <g id="line2d_3">
       <g>
-       <use xlink:href="#mc298820655" x="355.2" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m981c6d9a00" x="355.2" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_3">
@@ -385,113 +385,44 @@ z
     <g id="ytick_1">
      <g id="line2d_4">
       <defs>
-       <path id="m8afccf3ad6" d="M 0 0 
+       <path id="m44caf53d1d" d="M 0 0 
 L -3.5 0 
 " style="stroke: #000000; stroke-width: 0.8"/>
       </defs>
       <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m44caf53d1d" x="57.6" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_5">
-      <!-- 0.0 -->
-      <g transform="translate(34.696875 311.383219) scale(0.1 -0.1)">
-       <defs>
-        <path id="DejaVuSans-2e" d="M 684 794 
-L 1344 794 
-L 1344 0 
-L 684 0 
-L 684 794 
-z
-" transform="scale(0.015625)"/>
-       </defs>
+      <!-- 0 -->
+      <g transform="translate(44.2375 311.383219) scale(0.1 -0.1)">
        <use xlink:href="#DejaVuSans-30"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-30" x="95.410156"/>
       </g>
      </g>
     </g>
     <g id="ytick_2">
      <g id="line2d_5">
       <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="264.642624" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m44caf53d1d" x="57.6" y="258.616711" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_6">
-      <!-- 0.5 -->
-      <g transform="translate(34.696875 268.441843) scale(0.1 -0.1)">
-       <defs>
-        <path id="DejaVuSans-35" d="M 691 4666 
-L 3169 4666 
-L 3169 4134 
-L 1269 4134 
-L 1269 2991 
-Q 1406 3038 1543 3061 
-Q 1681 3084 1819 3084 
-Q 2600 3084 3056 2656 
-Q 3513 2228 3513 1497 
-Q 3513 744 3044 326 
-Q 2575 -91 1722 -91 
-Q 1428 -91 1123 -41 
-Q 819 9 494 109 
-L 494 744 
-Q 775 591 1075 516 
-Q 1375 441 1709 441 
-Q 2250 441 2565 725 
-Q 2881 1009 2881 1497 
-Q 2881 1984 2565 2268 
-Q 2250 2553 1709 2553 
-Q 1456 2553 1204 2497 
-Q 953 2441 691 2322 
-L 691 4666 
-z
-" transform="scale(0.015625)"/>
-       </defs>
-       <use xlink:href="#DejaVuSans-30"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-35" x="95.410156"/>
+      <!-- 10 -->
+      <g transform="translate(37.875 262.415929) scale(0.1 -0.1)">
+       <use xlink:href="#DejaVuSans-31"/>
+       <use xlink:href="#DejaVuSans-30" x="63.623047"/>
       </g>
      </g>
     </g>
     <g id="ytick_3">
      <g id="line2d_6">
       <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="221.701248" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m44caf53d1d" x="57.6" y="209.649421" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_7">
-      <!-- 1.0 -->
-      <g transform="translate(34.696875 225.500467) scale(0.1 -0.1)">
-       <use xlink:href="#DejaVuSans-31"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-30" x="95.410156"/>
-      </g>
-     </g>
-    </g>
-    <g id="ytick_4">
-     <g id="line2d_7">
-      <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="178.759873" style="stroke: 
#000000; stroke-width: 0.8"/>
-      </g>
-     </g>
-     <g id="text_8">
-      <!-- 1.5 -->
-      <g transform="translate(34.696875 182.559091) scale(0.1 -0.1)">
-       <use xlink:href="#DejaVuSans-31"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-35" x="95.410156"/>
-      </g>
-     </g>
-    </g>
-    <g id="ytick_5">
-     <g id="line2d_8">
-      <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="135.818497" style="stroke: 
#000000; stroke-width: 0.8"/>
-      </g>
-     </g>
-     <g id="text_9">
-      <!-- 2.0 -->
-      <g transform="translate(34.696875 139.617716) scale(0.1 -0.1)">
+      <!-- 20 -->
+      <g transform="translate(37.875 213.44864) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-32" d="M 1228 531 
 L 3431 531 
@@ -519,35 +450,19 @@ z
 " transform="scale(0.015625)"/>
        </defs>
        <use xlink:href="#DejaVuSans-32"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-30" x="95.410156"/>
-      </g>
-     </g>
-    </g>
-    <g id="ytick_6">
-     <g id="line2d_9">
-      <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="92.877121" style="stroke: 
#000000; stroke-width: 0.8"/>
-      </g>
-     </g>
-     <g id="text_10">
-      <!-- 2.5 -->
-      <g transform="translate(34.696875 96.67634) scale(0.1 -0.1)">
-       <use xlink:href="#DejaVuSans-32"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-35" x="95.410156"/>
+       <use xlink:href="#DejaVuSans-30" x="63.623047"/>
       </g>
      </g>
     </g>
-    <g id="ytick_7">
-     <g id="line2d_10">
+    <g id="ytick_4">
+     <g id="line2d_7">
       <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="49.935745" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m44caf53d1d" x="57.6" y="160.682132" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
-     <g id="text_11">
-      <!-- 3.0 -->
-      <g transform="translate(34.696875 53.734964) scale(0.1 -0.1)">
+     <g id="text_8">
+      <!-- 30 -->
+      <g transform="translate(37.875 164.48135) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-33" d="M 2597 2516 
 Q 3050 2419 3304 2112 
@@ -583,14 +498,89 @@ z
 " transform="scale(0.015625)"/>
        </defs>
        <use xlink:href="#DejaVuSans-33"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-30" x="95.410156"/>
+       <use xlink:href="#DejaVuSans-30" x="63.623047"/>
       </g>
      </g>
     </g>
-    <g id="text_12">
+    <g id="ytick_5">
+     <g id="line2d_8">
+      <g>
+       <use xlink:href="#m44caf53d1d" x="57.6" y="111.714842" style="stroke: 
#000000; stroke-width: 0.8"/>
+      </g>
+     </g>
+     <g id="text_9">
+      <!-- 40 -->
+      <g transform="translate(37.875 115.514061) scale(0.1 -0.1)">
+       <defs>
+        <path id="DejaVuSans-34" d="M 2419 4116 
+L 825 1625 
+L 2419 1625 
+L 2419 4116 
+z
+M 2253 4666 
+L 3047 4666 
+L 3047 1625 
+L 3713 1625 
+L 3713 1100 
+L 3047 1100 
+L 3047 0 
+L 2419 0 
+L 2419 1100 
+L 313 1100 
+L 313 1709 
+L 2253 4666 
+z
+" transform="scale(0.015625)"/>
+       </defs>
+       <use xlink:href="#DejaVuSans-34"/>
+       <use xlink:href="#DejaVuSans-30" x="63.623047"/>
+      </g>
+     </g>
+    </g>
+    <g id="ytick_6">
+     <g id="line2d_9">
+      <g>
+       <use xlink:href="#m44caf53d1d" x="57.6" y="62.747553" style="stroke: 
#000000; stroke-width: 0.8"/>
+      </g>
+     </g>
+     <g id="text_10">
+      <!-- 50 -->
+      <g transform="translate(37.875 66.546772) scale(0.1 -0.1)">
+       <defs>
+        <path id="DejaVuSans-35" d="M 691 4666 
+L 3169 4666 
+L 3169 4134 
+L 1269 4134 
+L 1269 2991 
+Q 1406 3038 1543 3061 
+Q 1681 3084 1819 3084 
+Q 2600 3084 3056 2656 
+Q 3513 2228 3513 1497 
+Q 3513 744 3044 326 
+Q 2575 -91 1722 -91 
+Q 1428 -91 1123 -41 
+Q 819 9 494 109 
+L 494 744 
+Q 775 591 1075 516 
+Q 1375 441 1709 441 
+Q 2250 441 2565 725 
+Q 2881 1009 2881 1497 
+Q 2881 1984 2565 2268 
+Q 2250 2553 1709 2553 
+Q 1456 2553 1204 2497 
+Q 953 2441 691 2322 
+L 691 4666 
+z
+" transform="scale(0.015625)"/>
+       </defs>
+       <use xlink:href="#DejaVuSans-35"/>
+       <use xlink:href="#DejaVuSans-30" x="63.623047"/>
+      </g>
+     </g>
+    </g>
+    <g id="text_11">
      <!-- Elapsed time (sec) -->
-     <g transform="translate(28.617187 220.976438) rotate(-90) scale(0.1 
-0.1)">
+     <g transform="translate(31.795312 220.976438) rotate(-90) scale(0.1 
-0.1)">
       <defs>
        <path id="DejaVuSans-45" d="M 628 4666 
 L 3578 4666 
@@ -785,32 +775,32 @@ z
      </g>
     </g>
    </g>
+   <g id="line2d_10">
+    <path clip-path="url(#p81d22f9aab)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+   </g>
    <g id="line2d_11">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p81d22f9aab)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_12">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p81d22f9aab)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_13">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p81d22f9aab)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_14">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p81d22f9aab)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_15">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p81d22f9aab)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_16">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p81d22f9aab)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_17">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p81d22f9aab)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_18">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
-   </g>
-   <g id="line2d_19">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p81d22f9aab)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="patch_12">
     <path d="M 57.6 307.584 
@@ -846,7 +836,7 @@ Q 62.6 108.1845 64.6 108.1845
 z
 " style="fill: #ffffff; opacity: 0.8; stroke: #cccccc; stroke-linejoin: 
miter"/>
     </g>
-    <g id="text_13">
+    <g id="text_12">
      <!-- Approach -->
      <g transform="translate(118.6 58.070438) scale(0.1 -0.1)">
       <defs>
@@ -904,7 +894,7 @@ L 66.6 65.748563
 z
 " style="fill: #1f77b4"/>
     </g>
-    <g id="text_14">
+    <g id="text_13">
      <!-- Apache Arrow Flight SQL -->
      <g transform="translate(94.6 72.748563) scale(0.1 -0.1)">
       <defs>
@@ -1071,29 +1061,43 @@ L 66.6 80.426688
 z
 " style="fill: #ff7f0e"/>
     </g>
-    <g id="text_15">
-     <!-- SELECT -->
+    <g id="text_14">
+     <!-- INSERT -->
      <g transform="translate(94.6 87.426688) scale(0.1 -0.1)">
       <defs>
-       <path id="DejaVuSans-43" d="M 4122 4306 
-L 4122 3641 
-Q 3803 3938 3442 4084 
-Q 3081 4231 2675 4231 
-Q 1875 4231 1450 3742 
-Q 1025 3253 1025 2328 
-Q 1025 1406 1450 917 
-Q 1875 428 2675 428 
-Q 3081 428 3442 575 
-Q 3803 722 4122 1019 
-L 4122 359 
-Q 3791 134 3420 21 
-Q 3050 -91 2638 -91 
-Q 1578 -91 968 557 
-Q 359 1206 359 2328 
-Q 359 3453 968 4101 
-Q 1578 4750 2638 4750 
-Q 3056 4750 3426 4639 
-Q 3797 4528 4122 4306 
+       <path id="DejaVuSans-49" d="M 628 4666 
+L 1259 4666 
+L 1259 0 
+L 628 0 
+L 628 4666 
+z
+" transform="scale(0.015625)"/>
+       <path id="DejaVuSans-52" d="M 2841 2188 
+Q 3044 2119 3236 1894 
+Q 3428 1669 3622 1275 
+L 4263 0 
+L 3584 0 
+L 2988 1197 
+Q 2756 1666 2539 1819 
+Q 2322 1972 1947 1972 
+L 1259 1972 
+L 1259 0 
+L 628 0 
+L 628 4666 
+L 2053 4666 
+Q 2853 4666 3247 4331 
+Q 3641 3997 3641 3322 
+Q 3641 2881 3436 2590 
+Q 3231 2300 2841 2188 
+z
+M 1259 4147 
+L 1259 2491 
+L 2053 2491 
+Q 2509 2491 2742 2702 
+Q 2975 2913 2975 3322 
+Q 2975 3731 2742 3939 
+Q 2509 4147 2053 4147 
+L 1259 4147 
 z
 " transform="scale(0.015625)"/>
        <path id="DejaVuSans-54" d="M -19 4666 
@@ -1108,12 +1112,12 @@ L -19 4666
 z
 " transform="scale(0.015625)"/>
       </defs>
-      <use xlink:href="#DejaVuSans-53"/>
-      <use xlink:href="#DejaVuSans-45" x="63.476562"/>
-      <use xlink:href="#DejaVuSans-4c" x="126.660156"/>
-      <use xlink:href="#DejaVuSans-45" x="182.373047"/>
-      <use xlink:href="#DejaVuSans-43" x="245.556641"/>
-      <use xlink:href="#DejaVuSans-54" x="315.380859"/>
+      <use xlink:href="#DejaVuSans-49"/>
+      <use xlink:href="#DejaVuSans-4e" x="29.492188"/>
+      <use xlink:href="#DejaVuSans-53" x="104.296875"/>
+      <use xlink:href="#DejaVuSans-45" x="167.773438"/>
+      <use xlink:href="#DejaVuSans-52" x="230.957031"/>
+      <use xlink:href="#DejaVuSans-54" x="293.189453"/>
      </g>
     </g>
     <g id="patch_19">
@@ -1124,10 +1128,31 @@ L 66.6 95.104813
 z
 " style="fill: #2ca02c"/>
     </g>
-    <g id="text_16">
+    <g id="text_15">
      <!-- COPY -->
      <g transform="translate(94.6 102.104813) scale(0.1 -0.1)">
       <defs>
+       <path id="DejaVuSans-43" d="M 4122 4306 
+L 4122 3641 
+Q 3803 3938 3442 4084 
+Q 3081 4231 2675 4231 
+Q 1875 4231 1450 3742 
+Q 1025 3253 1025 2328 
+Q 1025 1406 1450 917 
+Q 1875 428 2675 428 
+Q 3081 428 3442 575 
+Q 3803 722 4122 1019 
+L 4122 359 
+Q 3791 134 3420 21 
+Q 3050 -91 2638 -91 
+Q 1578 -91 968 557 
+Q 359 1206 359 2328 
+Q 359 3453 968 4101 
+Q 1578 4750 2638 4750 
+Q 3056 4750 3426 4639 
+Q 3797 4528 4122 4306 
+z
+" transform="scale(0.015625)"/>
        <path id="DejaVuSans-4f" d="M 2522 4238 
 Q 1834 4238 1429 3725 
 Q 1025 3213 1025 2328 
@@ -1193,7 +1218,7 @@ z
   </g>
  </g>
  <defs>
-  <clipPath id="p3aca9fb4c4">
+  <clipPath id="p81d22f9aab">
    <rect x="57.6" y="41.472" width="357.12" height="266.112"/>
   </clipPath>
  </defs>
diff --git a/benchmark/integer/result.csv b/benchmark/integer/result.csv
deleted file mode 100644
index bb27a19..0000000
--- a/benchmark/integer/result.csv
+++ /dev/null
@@ -1,10 +0,0 @@
-Approach,N records,Elapsed time (sec)
-Apache Arrow Flight SQL,100000,0.015
-SELECT,100000,0.015
-COPY,100000,0.012
-Apache Arrow Flight SQL,1000000,0.111
-SELECT,1000000,0.148
-COPY,1000000,0.114
-Apache Arrow Flight SQL,10000000,0.958
-SELECT,10000000,1.502
-COPY,10000000,1.162
diff --git a/benchmark/integer/select.csv b/benchmark/integer/select.csv
new file mode 100644
index 0000000..90fec54
--- /dev/null
+++ b/benchmark/integer/select.csv
@@ -0,0 +1,10 @@
+Approach,N records,Elapsed time (sec)
+Apache Arrow Flight SQL,100000,0.014
+SELECT,100000,0.015
+COPY,100000,0.011
+Apache Arrow Flight SQL,1000000,0.082
+SELECT,1000000,0.145
+COPY,1000000,0.110
+Apache Arrow Flight SQL,10000000,0.694
+SELECT,10000000,1.486
+COPY,10000000,1.142
diff --git a/benchmark/integer/result.svg b/benchmark/integer/select.svg
similarity index 90%
copy from benchmark/integer/result.svg
copy to benchmark/integer/select.svg
index f8ed487..8703293 100644
--- a/benchmark/integer/result.svg
+++ b/benchmark/integer/select.svg
@@ -6,7 +6,7 @@
   <rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/"; 
xmlns:cc="http://creativecommons.org/ns#"; 
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";>
    <cc:Work>
     <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:date>2023-11-13T18:19:07.890284</dc:date>
+    <dc:date>2023-11-16T18:51:19.944464</dc:date>
     <dc:format>image/svg+xml</dc:format>
     <dc:creator>
      <cc:Agent>
@@ -40,42 +40,42 @@ z
    <g id="patch_3">
     <path d="M 69.82144 307.584 
 L 100.93056 307.584 
-L 100.93056 305.052975 
-L 69.82144 305.052975 
+L 100.93056 305.196275 
+L 69.82144 305.196275 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #1f77b4"/>
+" clip-path="url(#p3c234d4b8c)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_4">
     <path d="M 188.86144 307.584 
 L 219.97056 307.584 
-L 219.97056 288.854413 
-L 188.86144 288.854413 
+L 219.97056 293.598751 
+L 188.86144 293.598751 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #1f77b4"/>
+" clip-path="url(#p3c234d4b8c)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_5">
     <path d="M 307.90144 307.584 
 L 339.01056 307.584 
-L 339.01056 145.935851 
-L 307.90144 145.935851 
+L 339.01056 189.221039 
+L 307.90144 189.221039 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #1f77b4"/>
+" clip-path="url(#p3c234d4b8c)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_6">
     <path d="M 101.56544 307.584 
 L 132.67456 307.584 
-L 132.67456 305.052975 
-L 101.56544 305.052975 
+L 132.67456 305.025723 
+L 101.56544 305.025723 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #ff7f0e"/>
+" clip-path="url(#p3c234d4b8c)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_7">
     <path d="M 220.60544 307.584 
 L 251.71456 307.584 
-L 251.71456 282.611217 
-L 220.60544 282.611217 
+L 251.71456 282.853987 
+L 220.60544 282.853987 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #ff7f0e"/>
+" clip-path="url(#p3c234d4b8c)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_8">
     <path d="M 339.64544 307.584 
@@ -83,42 +83,42 @@ L 370.75456 307.584
 L 370.75456 54.144 
 L 339.64544 54.144 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #ff7f0e"/>
+" clip-path="url(#p3c234d4b8c)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_9">
     <path d="M 133.30944 307.584 
 L 164.41856 307.584 
-L 164.41856 305.55918 
-L 133.30944 305.55918 
+L 164.41856 305.70793 
+L 133.30944 305.70793 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #2ca02c"/>
+" clip-path="url(#p3c234d4b8c)" style="fill: #2ca02c"/>
    </g>
    <g id="patch_10">
     <path d="M 252.34944 307.584 
 L 283.45856 307.584 
-L 283.45856 288.348208 
-L 252.34944 288.348208 
+L 283.45856 288.8233 
+L 252.34944 288.8233 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #2ca02c"/>
+" clip-path="url(#p3c234d4b8c)" style="fill: #2ca02c"/>
    </g>
    <g id="patch_11">
     <path d="M 371.38944 307.584 
 L 402.49856 307.584 
-L 402.49856 111.513907 
-L 371.38944 111.513907 
+L 402.49856 112.813825 
+L 371.38944 112.813825 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #2ca02c"/>
+" clip-path="url(#p3c234d4b8c)" style="fill: #2ca02c"/>
    </g>
    <g id="matplotlib.axis_1">
     <g id="xtick_1">
      <g id="line2d_1">
       <defs>
-       <path id="mdc567500bd" d="M 0 0 
+       <path id="mde4eb57f12" d="M 0 0 
 L 0 3.5 
 " style="stroke: #000000; stroke-width: 0.8"/>
       </defs>
       <g>
-       <use xlink:href="#mdc567500bd" x="117.12" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#mde4eb57f12" x="117.12" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_1">
@@ -173,7 +173,7 @@ z
     <g id="xtick_2">
      <g id="line2d_2">
       <g>
-       <use xlink:href="#mdc567500bd" x="236.16" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#mde4eb57f12" x="236.16" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_2">
@@ -192,7 +192,7 @@ z
     <g id="xtick_3">
      <g id="line2d_3">
       <g>
-       <use xlink:href="#mdc567500bd" x="355.2" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#mde4eb57f12" x="355.2" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_3">
@@ -385,12 +385,12 @@ z
     <g id="ytick_1">
      <g id="line2d_4">
       <defs>
-       <path id="m3c2589d813" d="M 0 0 
+       <path id="m1fdc82ad0c" d="M 0 0 
 L -3.5 0 
 " style="stroke: #000000; stroke-width: 0.8"/>
       </defs>
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m1fdc82ad0c" x="57.6" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_5">
@@ -414,12 +414,12 @@ z
     <g id="ytick_2">
      <g id="line2d_5">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="273.836996" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m1fdc82ad0c" x="57.6" y="273.473637" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_6">
       <!-- 0.2 -->
-      <g transform="translate(34.696875 277.636215) scale(0.1 -0.1)">
+      <g transform="translate(34.696875 277.272855) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-32" d="M 1228 531 
 L 3431 531 
@@ -455,12 +455,12 @@ z
     <g id="ytick_3">
      <g id="line2d_6">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="240.089992" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m1fdc82ad0c" x="57.6" y="239.363273" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_7">
       <!-- 0.4 -->
-      <g transform="translate(34.696875 243.889211) scale(0.1 -0.1)">
+      <g transform="translate(34.696875 243.162492) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-34" d="M 2419 4116 
 L 825 1625 
@@ -491,12 +491,12 @@ z
     <g id="ytick_4">
      <g id="line2d_7">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="206.342988" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m1fdc82ad0c" x="57.6" y="205.25291" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_8">
       <!-- 0.6 -->
-      <g transform="translate(34.696875 210.142207) scale(0.1 -0.1)">
+      <g transform="translate(34.696875 209.052129) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-36" d="M 2113 2584 
 Q 1688 2584 1439 2293 
@@ -538,12 +538,12 @@ z
     <g id="ytick_5">
      <g id="line2d_8">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="172.595984" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m1fdc82ad0c" x="57.6" y="171.142546" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_9">
       <!-- 0.8 -->
-      <g transform="translate(34.696875 176.395203) scale(0.1 -0.1)">
+      <g transform="translate(34.696875 174.941765) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-38" d="M 2034 2216 
 Q 1584 2216 1326 1975 
@@ -594,12 +594,12 @@ z
     <g id="ytick_6">
      <g id="line2d_9">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="138.84898" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m1fdc82ad0c" x="57.6" y="137.032183" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_10">
       <!-- 1.0 -->
-      <g transform="translate(34.696875 142.648199) scale(0.1 -0.1)">
+      <g transform="translate(34.696875 140.831402) scale(0.1 -0.1)">
        <use xlink:href="#DejaVuSans-31"/>
        <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
        <use xlink:href="#DejaVuSans-30" x="95.410156"/>
@@ -609,12 +609,12 @@ z
     <g id="ytick_7">
      <g id="line2d_10">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="105.101976" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m1fdc82ad0c" x="57.6" y="102.92182" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_11">
       <!-- 1.2 -->
-      <g transform="translate(34.696875 108.901195) scale(0.1 -0.1)">
+      <g transform="translate(34.696875 106.721038) scale(0.1 -0.1)">
        <use xlink:href="#DejaVuSans-31"/>
        <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
        <use xlink:href="#DejaVuSans-32" x="95.410156"/>
@@ -624,12 +624,12 @@ z
     <g id="ytick_8">
      <g id="line2d_11">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="71.354972" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m1fdc82ad0c" x="57.6" y="68.811456" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_12">
       <!-- 1.4 -->
-      <g transform="translate(34.696875 75.154191) scale(0.1 -0.1)">
+      <g transform="translate(34.696875 72.610675) scale(0.1 -0.1)">
        <use xlink:href="#DejaVuSans-31"/>
        <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
        <use xlink:href="#DejaVuSans-34" x="95.410156"/>
@@ -834,31 +834,31 @@ z
     </g>
    </g>
    <g id="line2d_12">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p3c234d4b8c)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_13">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p3c234d4b8c)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_14">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p3c234d4b8c)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_15">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p3c234d4b8c)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_16">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p3c234d4b8c)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_17">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p3c234d4b8c)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_18">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p3c234d4b8c)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_19">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p3c234d4b8c)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_20">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p3c234d4b8c)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="patch_12">
     <path d="M 57.6 307.584 
@@ -1241,7 +1241,7 @@ z
   </g>
  </g>
  <defs>
-  <clipPath id="pe972ace1b8">
+  <clipPath id="p3c234d4b8c">
    <rect x="57.6" y="41.472" width="357.12" height="266.112"/>
   </clipPath>
  </defs>
diff --git a/benchmark/markdown.rb b/benchmark/markdown.rb
index e4225e4..f06ad17 100755
--- a/benchmark/markdown.rb
+++ b/benchmark/markdown.rb
@@ -24,6 +24,11 @@ benchmarks = [
   "string",
 ]
 
+types = [
+  "select",
+  "insert",
+]
+
 def format_n_records(n_records)
   if n_records < 1_000_000
     "%dK" % (n_records / 1_000.0)
@@ -34,44 +39,51 @@ end
 
 benchmarks.each do |benchmark|
   base_dir = File.join(__dir__, benchmark)
-  data = CSV.read(File.join(base_dir, "result.csv"),
-                  headers: true,
-                  converters: :all)
   readme_path = File.join(base_dir, "README.md")
-  graph_markdown = "![Graph](result.svg)"
+  results_header = "## Results"
   readme = File.read(readme_path)
-  readme_before_graph_markdown =
-    readme.split(/^#{Regexp.escape(graph_markdown)}$/, 2)[0]
-  records_per_n = data.each.group_by do |row|
-    row["N records"]
-  end
-  result = ""
-  records_per_n.each do |n_records, rows|
-    result << "\n"
-    result << "#{format_n_records(n_records)} records:\n"
-    result << "\n"
-    approaches = rows.collect do |row|
-      approach = row["Approach"]
-      if approach == "Apache Arrow Flight SQL"
-        approach
-      else
-        "`#{approach}`"
-      end
+  readme_before_results_header =
+    readme.split(/^#{Regexp.escape(results_header)}$/, 2)[0]
+  results = ""
+  types.each do |type|
+    results << "### `#{type.upcase}`\n"
+    results << "\n"
+    results << "![Graph](#{type}.svg)"
+    results << "\n"
+    data = CSV.read(File.join(base_dir, "#{type}.csv"),
+                    headers: true,
+                    converters: :all)
+    records_per_n = data.each.group_by do |row|
+      row["N records"]
     end
-    result << ("| " + approaches.join(" | ") + " |\n")
-    separators = approaches.collect {|approach| "-" * approach.size}
-    result << ("| " + separators.join(" | ") + " |\n")
-    formatted_elapsed = approaches.zip(rows).collect do |approach, row|
-      width = approach.size
-      ("%.3f" % row["Elapsed time (sec)"]).ljust(width)
+    records_per_n.each do |n_records, rows|
+      results << "\n"
+      results << "#{format_n_records(n_records)} records:\n"
+      results << "\n"
+      approaches = rows.collect do |row|
+        approach = row["Approach"]
+        if approach == "Apache Arrow Flight SQL"
+          approach
+        else
+          "`#{approach}`"
+        end
+      end
+      results << ("| " + approaches.join(" | ") + " |\n")
+      separators = approaches.collect {|approach| "-" * approach.size}
+      results << ("| " + separators.join(" | ") + " |\n")
+      formatted_elapsed = approaches.zip(rows).collect do |approach, row|
+        width = approach.size
+        ("%.3f" % row["Elapsed time (sec)"]).ljust(width)
+      end
+      results << ("| " + formatted_elapsed.join(" | ") + " |\n")
     end
-    result << ("| " + formatted_elapsed.join(" | ") + " |\n")
+    results << "\n"
   end
   File.write(readme_path, <<-README)
-#{readme_before_graph_markdown.strip}
+#{readme_before_results_header.strip}
 
-#{graph_markdown}
+#{results_header}
 
-#{result.strip}
+#{results.strip}
   README
 end
diff --git a/benchmark/meson.build b/benchmark/meson.build
index dfb06a0..1f07151 100644
--- a/benchmark/meson.build
+++ b/benchmark/meson.build
@@ -16,5 +16,8 @@
 # under the License.
 
 libpq = dependency('libpq')
-executable('copy', 'copy.c', dependencies: [libpq, postgresql])
+
+executable('insert', 'insert.cc', dependencies: [libpq, postgresql])
+executable('insert-copy', 'insert-copy.cc', dependencies: [libpq, postgresql])
 executable('select', 'select.c', dependencies: [libpq, postgresql])
+executable('select-copy', 'select-copy.c', dependencies: [libpq, postgresql])
diff --git a/benchmark/run.sh b/benchmark/run.sh
index eaf8baa..0e6ced9 100755
--- a/benchmark/run.sh
+++ b/benchmark/run.sh
@@ -35,8 +35,11 @@ benchmarks+=(integer)
 benchmarks+=(string)
 
 for benchmark in "${benchmarks[@]}"; do
-  result="${base_dir}/${benchmark}/result.csv"
-  echo "Approach,N records,Elapsed time (sec)" | tee "${result}"
+  select_result="${base_dir}/${benchmark}/select.csv"
+  insert_result="${base_dir}/${benchmark}/insert.csv"
+  echo "Approach,N records,Elapsed time (sec)" | \
+    tee "${select_result}" \
+        "${insert_result}"
   sizes=()
   sizes+=(100000)
   sizes+=(1000000)
@@ -47,16 +50,30 @@ for benchmark in "${benchmarks[@]}"; do
     "${base_dir}/${benchmark}/prepare-sql.sh" "${size}" "${PGDATABASE}" | \
       psql -d postgres
 
-    echo "${benchmark}: ${size}: Apache Arrow Flight SQL"
-    elapsed_time=$(measure "${base_dir}/select.rb")
-    echo "Apache Arrow Flight SQL,${size},${elapsed_time}" | tee -a "${result}"
+    echo "${benchmark}: select: ${size}: Apache Arrow Flight SQL"
+    elapsed_time=$(measure "${base_dir}/select-flight-sql.rb")
+    echo "Apache Arrow Flight SQL,${size},${elapsed_time}" | \
+      tee -a "${select_result}"
 
-    echo "${benchmark}: ${size}: SELECT"
+    echo "${benchmark}: select: ${size}: SELECT"
     elapsed_time=$(measure benchmark/select)
-    echo "SELECT,${size},${elapsed_time}" | tee -a "${result}"
+    echo "SELECT,${size},${elapsed_time}" | tee -a "${select_result}"
 
-    echo "${benchmark}: ${size}: COPY"
-    elapsed_time=$(measure benchmark/copy)
-    echo "COPY,${size},${elapsed_time}" | tee -a "${result}"
+    echo "${benchmark}: select: ${size}: COPY"
+    elapsed_time=$(measure benchmark/select-copy)
+    echo "COPY,${size},${elapsed_time}" | tee -a "${select_result}"
+
+    echo "${benchmark}: insert: ${size}: Apache Arrow Flight SQL"
+    elapsed_time=$(measure "${base_dir}/insert-flight-sql.rb")
+    echo "Apache Arrow Flight SQL,${size},${elapsed_time}" | \
+      tee -a "${insert_result}"
+
+    echo "${benchmark}: insert: ${size}: INSERT"
+    elapsed_time=$(measure benchmark/insert)
+    echo "INSERT,${size},${elapsed_time}" | tee -a "${insert_result}"
+
+    echo "${benchmark}: insert: ${size}: COPY"
+    elapsed_time=$(measure benchmark/insert-copy)
+    echo "COPY,${size},${elapsed_time}" | tee -a "${insert_result}"
   done
 done
diff --git a/benchmark/copy.c b/benchmark/select-copy.c
similarity index 100%
rename from benchmark/copy.c
rename to benchmark/select-copy.c
diff --git a/benchmark/select.rb b/benchmark/select-flight-sql.rb
similarity index 100%
rename from benchmark/select.rb
rename to benchmark/select-flight-sql.rb
diff --git a/benchmark/string/README.md b/benchmark/string/README.md
index 473f7c4..d0f2594 100644
--- a/benchmark/string/README.md
+++ b/benchmark/string/README.md
@@ -23,7 +23,7 @@
 
 See the [`README.md` in the parent directory](../README.md).
 
-## Result
+## Environment
 
 Here is a benchmark result on the following environment:
 
@@ -38,22 +38,48 @@ Here is a benchmark result on the following environment:
   0.2.0 (not released yet)
   14df9b5fe61eda2d71bdfbf67c61a227741f616c
 
-![Graph](result.svg)
+## Results
+
+### `SELECT`
+
+![Graph](select.svg)
 
 100K records:
 
 | Apache Arrow Flight SQL | `SELECT` | `COPY` |
 | ----------------------- | -------- | ------ |
-| 0.047                   | 0.017    | 0.017  |
+| 0.041                   | 0.016    | 0.016  |
 
 1M records:
 
 | Apache Arrow Flight SQL | `SELECT` | `COPY` |
 | ----------------------- | -------- | ------ |
-| 0.512                   | 0.155    | 0.153  |
+| 0.353                   | 0.149    | 0.148  |
 
 10M records:
 
 | Apache Arrow Flight SQL | `SELECT` | `COPY` |
 | ----------------------- | -------- | ------ |
-| 2.951                   | 1.706    | 1.640  |
+| 2.154                   | 1.924    | 1.596  |
+
+### `INSERT`
+
+![Graph](insert.svg)
+
+100K records:
+
+| Apache Arrow Flight SQL | `INSERT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 0.343                   | 0.338    | 0.416  |
+
+1M records:
+
+| Apache Arrow Flight SQL | `INSERT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 6.906                   | 5.730    | 2.870  |
+
+10M records:
+
+| Apache Arrow Flight SQL | `INSERT` | `COPY` |
+| ----------------------- | -------- | ------ |
+| 116.579                 | 107.045  | 66.410 |
diff --git a/benchmark/string/insert.csv b/benchmark/string/insert.csv
new file mode 100644
index 0000000..73f8bb7
--- /dev/null
+++ b/benchmark/string/insert.csv
@@ -0,0 +1,10 @@
+Approach,N records,Elapsed time (sec)
+Apache Arrow Flight SQL,100000,0.343
+INSERT,100000,0.338
+COPY,100000,0.416
+Apache Arrow Flight SQL,1000000,6.906
+INSERT,1000000,5.730
+COPY,1000000,2.870
+Apache Arrow Flight SQL,10000000,116.579
+INSERT,10000000,107.045
+COPY,10000000,66.410
diff --git a/benchmark/integer/result.svg b/benchmark/string/insert.svg
similarity index 84%
rename from benchmark/integer/result.svg
rename to benchmark/string/insert.svg
index f8ed487..cb8e05a 100644
--- a/benchmark/integer/result.svg
+++ b/benchmark/string/insert.svg
@@ -6,7 +6,7 @@
   <rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/"; 
xmlns:cc="http://creativecommons.org/ns#"; 
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";>
    <cc:Work>
     <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:date>2023-11-13T18:19:07.890284</dc:date>
+    <dc:date>2023-11-16T18:51:20.038826</dc:date>
     <dc:format>image/svg+xml</dc:format>
     <dc:creator>
      <cc:Agent>
@@ -40,85 +40,85 @@ z
    <g id="patch_3">
     <path d="M 69.82144 307.584 
 L 100.93056 307.584 
-L 100.93056 305.052975 
-L 69.82144 305.052975 
+L 100.93056 306.838326 
+L 69.82144 306.838326 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #1f77b4"/>
+" clip-path="url(#p1ecb086c24)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_4">
     <path d="M 188.86144 307.584 
 L 219.97056 307.584 
-L 219.97056 288.854413 
-L 188.86144 288.854413 
+L 219.97056 292.570519 
+L 188.86144 292.570519 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #1f77b4"/>
+" clip-path="url(#p1ecb086c24)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_5">
     <path d="M 307.90144 307.584 
 L 339.01056 307.584 
-L 339.01056 145.935851 
-L 307.90144 145.935851 
+L 339.01056 54.144 
+L 307.90144 54.144 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #1f77b4"/>
+" clip-path="url(#p1ecb086c24)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_6">
     <path d="M 101.56544 307.584 
 L 132.67456 307.584 
-L 132.67456 305.052975 
-L 101.56544 305.052975 
+L 132.67456 306.849196 
+L 101.56544 306.849196 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #ff7f0e"/>
+" clip-path="url(#p1ecb086c24)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_7">
     <path d="M 220.60544 307.584 
 L 251.71456 307.584 
-L 251.71456 282.611217 
-L 220.60544 282.611217 
+L 251.71456 295.127115 
+L 220.60544 295.127115 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #ff7f0e"/>
+" clip-path="url(#p1ecb086c24)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_8">
     <path d="M 339.64544 307.584 
 L 370.75456 307.584 
-L 370.75456 54.144 
-L 339.64544 54.144 
+L 370.75456 74.870691 
+L 339.64544 74.870691 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #ff7f0e"/>
+" clip-path="url(#p1ecb086c24)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_9">
     <path d="M 133.30944 307.584 
 L 164.41856 307.584 
-L 164.41856 305.55918 
-L 133.30944 305.55918 
+L 164.41856 306.679626 
+L 133.30944 306.679626 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #2ca02c"/>
+" clip-path="url(#p1ecb086c24)" style="fill: #2ca02c"/>
    </g>
    <g id="patch_10">
     <path d="M 252.34944 307.584 
 L 283.45856 307.584 
-L 283.45856 288.348208 
-L 252.34944 288.348208 
+L 283.45856 301.344688 
+L 252.34944 301.344688 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #2ca02c"/>
+" clip-path="url(#p1ecb086c24)" style="fill: #2ca02c"/>
    </g>
    <g id="patch_11">
     <path d="M 371.38944 307.584 
 L 402.49856 307.584 
-L 402.49856 111.513907 
-L 371.38944 111.513907 
+L 402.49856 163.210224 
+L 371.38944 163.210224 
 z
-" clip-path="url(#pe972ace1b8)" style="fill: #2ca02c"/>
+" clip-path="url(#p1ecb086c24)" style="fill: #2ca02c"/>
    </g>
    <g id="matplotlib.axis_1">
     <g id="xtick_1">
      <g id="line2d_1">
       <defs>
-       <path id="mdc567500bd" d="M 0 0 
+       <path id="ma4a065f076" d="M 0 0 
 L 0 3.5 
 " style="stroke: #000000; stroke-width: 0.8"/>
       </defs>
       <g>
-       <use xlink:href="#mdc567500bd" x="117.12" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#ma4a065f076" x="117.12" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_1">
@@ -173,7 +173,7 @@ z
     <g id="xtick_2">
      <g id="line2d_2">
       <g>
-       <use xlink:href="#mdc567500bd" x="236.16" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#ma4a065f076" x="236.16" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_2">
@@ -192,7 +192,7 @@ z
     <g id="xtick_3">
      <g id="line2d_3">
       <g>
-       <use xlink:href="#mdc567500bd" x="355.2" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#ma4a065f076" x="355.2" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_3">
@@ -385,41 +385,30 @@ z
     <g id="ytick_1">
      <g id="line2d_4">
       <defs>
-       <path id="m3c2589d813" d="M 0 0 
+       <path id="mb94ee7c6db" d="M 0 0 
 L -3.5 0 
 " style="stroke: #000000; stroke-width: 0.8"/>
       </defs>
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#mb94ee7c6db" x="57.6" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_5">
-      <!-- 0.0 -->
-      <g transform="translate(34.696875 311.383219) scale(0.1 -0.1)">
-       <defs>
-        <path id="DejaVuSans-2e" d="M 684 794 
-L 1344 794 
-L 1344 0 
-L 684 0 
-L 684 794 
-z
-" transform="scale(0.015625)"/>
-       </defs>
+      <!-- 0 -->
+      <g transform="translate(44.2375 311.383219) scale(0.1 -0.1)">
        <use xlink:href="#DejaVuSans-30"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-30" x="95.410156"/>
       </g>
      </g>
     </g>
     <g id="ytick_2">
      <g id="line2d_5">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="273.836996" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#mb94ee7c6db" x="57.6" y="264.104471" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_6">
-      <!-- 0.2 -->
-      <g transform="translate(34.696875 277.636215) scale(0.1 -0.1)">
+      <!-- 20 -->
+      <g transform="translate(37.875 267.90369) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-32" d="M 1228 531 
 L 3431 531 
@@ -446,21 +435,20 @@ Q 1991 1309 1228 531
 z
 " transform="scale(0.015625)"/>
        </defs>
-       <use xlink:href="#DejaVuSans-30"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-32" x="95.410156"/>
+       <use xlink:href="#DejaVuSans-32"/>
+       <use xlink:href="#DejaVuSans-30" x="63.623047"/>
       </g>
      </g>
     </g>
     <g id="ytick_3">
      <g id="line2d_6">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="240.089992" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#mb94ee7c6db" x="57.6" y="220.624942" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_7">
-      <!-- 0.4 -->
-      <g transform="translate(34.696875 243.889211) scale(0.1 -0.1)">
+      <!-- 40 -->
+      <g transform="translate(37.875 224.424161) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-34" d="M 2419 4116 
 L 825 1625 
@@ -482,21 +470,20 @@ L 2253 4666
 z
 " transform="scale(0.015625)"/>
        </defs>
-       <use xlink:href="#DejaVuSans-30"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-34" x="95.410156"/>
+       <use xlink:href="#DejaVuSans-34"/>
+       <use xlink:href="#DejaVuSans-30" x="63.623047"/>
       </g>
      </g>
     </g>
     <g id="ytick_4">
      <g id="line2d_7">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="206.342988" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#mb94ee7c6db" x="57.6" y="177.145413" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_8">
-      <!-- 0.6 -->
-      <g transform="translate(34.696875 210.142207) scale(0.1 -0.1)">
+      <!-- 60 -->
+      <g transform="translate(37.875 180.944632) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-36" d="M 2113 2584 
 Q 1688 2584 1439 2293 
@@ -529,21 +516,20 @@ Q 3103 4656 3366 4563
 z
 " transform="scale(0.015625)"/>
        </defs>
-       <use xlink:href="#DejaVuSans-30"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-36" x="95.410156"/>
+       <use xlink:href="#DejaVuSans-36"/>
+       <use xlink:href="#DejaVuSans-30" x="63.623047"/>
       </g>
      </g>
     </g>
     <g id="ytick_5">
      <g id="line2d_8">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="172.595984" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#mb94ee7c6db" x="57.6" y="133.665884" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_9">
-      <!-- 0.8 -->
-      <g transform="translate(34.696875 176.395203) scale(0.1 -0.1)">
+      <!-- 80 -->
+      <g transform="translate(37.875 137.465103) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-38" d="M 2034 2216 
 Q 1584 2216 1326 1975 
@@ -585,60 +571,44 @@ Q 1172 3844 1172 3481
 z
 " transform="scale(0.015625)"/>
        </defs>
-       <use xlink:href="#DejaVuSans-30"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-38" x="95.410156"/>
+       <use xlink:href="#DejaVuSans-38"/>
+       <use xlink:href="#DejaVuSans-30" x="63.623047"/>
       </g>
      </g>
     </g>
     <g id="ytick_6">
      <g id="line2d_9">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="138.84898" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#mb94ee7c6db" x="57.6" y="90.186355" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_10">
-      <!-- 1.0 -->
-      <g transform="translate(34.696875 142.648199) scale(0.1 -0.1)">
+      <!-- 100 -->
+      <g transform="translate(31.5125 93.985574) scale(0.1 -0.1)">
        <use xlink:href="#DejaVuSans-31"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-30" x="95.410156"/>
+       <use xlink:href="#DejaVuSans-30" x="63.623047"/>
+       <use xlink:href="#DejaVuSans-30" x="127.246094"/>
       </g>
      </g>
     </g>
     <g id="ytick_7">
      <g id="line2d_10">
       <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="105.101976" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#mb94ee7c6db" x="57.6" y="46.706827" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_11">
-      <!-- 1.2 -->
-      <g transform="translate(34.696875 108.901195) scale(0.1 -0.1)">
-       <use xlink:href="#DejaVuSans-31"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-32" x="95.410156"/>
-      </g>
-     </g>
-    </g>
-    <g id="ytick_8">
-     <g id="line2d_11">
-      <g>
-       <use xlink:href="#m3c2589d813" x="57.6" y="71.354972" style="stroke: 
#000000; stroke-width: 0.8"/>
-      </g>
-     </g>
-     <g id="text_12">
-      <!-- 1.4 -->
-      <g transform="translate(34.696875 75.154191) scale(0.1 -0.1)">
+      <!-- 120 -->
+      <g transform="translate(31.5125 50.506045) scale(0.1 -0.1)">
        <use xlink:href="#DejaVuSans-31"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-34" x="95.410156"/>
+       <use xlink:href="#DejaVuSans-32" x="63.623047"/>
+       <use xlink:href="#DejaVuSans-30" x="127.246094"/>
       </g>
      </g>
     </g>
-    <g id="text_13">
+    <g id="text_12">
      <!-- Elapsed time (sec) -->
-     <g transform="translate(28.617187 220.976438) rotate(-90) scale(0.1 
-0.1)">
+     <g transform="translate(25.432812 220.976438) rotate(-90) scale(0.1 
-0.1)">
       <defs>
        <path id="DejaVuSans-45" d="M 628 4666 
 L 3578 4666 
@@ -833,32 +803,32 @@ z
      </g>
     </g>
    </g>
+   <g id="line2d_11">
+    <path clip-path="url(#p1ecb086c24)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+   </g>
    <g id="line2d_12">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p1ecb086c24)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_13">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p1ecb086c24)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_14">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p1ecb086c24)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_15">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p1ecb086c24)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_16">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p1ecb086c24)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_17">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p1ecb086c24)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_18">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p1ecb086c24)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_19">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
-   </g>
-   <g id="line2d_20">
-    <path clip-path="url(#pe972ace1b8)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p1ecb086c24)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="patch_12">
     <path d="M 57.6 307.584 
@@ -894,7 +864,7 @@ Q 62.6 108.1845 64.6 108.1845
 z
 " style="fill: #ffffff; opacity: 0.8; stroke: #cccccc; stroke-linejoin: 
miter"/>
     </g>
-    <g id="text_14">
+    <g id="text_13">
      <!-- Approach -->
      <g transform="translate(118.6 58.070438) scale(0.1 -0.1)">
       <defs>
@@ -952,7 +922,7 @@ L 66.6 65.748563
 z
 " style="fill: #1f77b4"/>
     </g>
-    <g id="text_15">
+    <g id="text_14">
      <!-- Apache Arrow Flight SQL -->
      <g transform="translate(94.6 72.748563) scale(0.1 -0.1)">
       <defs>
@@ -1119,29 +1089,43 @@ L 66.6 80.426688
 z
 " style="fill: #ff7f0e"/>
     </g>
-    <g id="text_16">
-     <!-- SELECT -->
+    <g id="text_15">
+     <!-- INSERT -->
      <g transform="translate(94.6 87.426688) scale(0.1 -0.1)">
       <defs>
-       <path id="DejaVuSans-43" d="M 4122 4306 
-L 4122 3641 
-Q 3803 3938 3442 4084 
-Q 3081 4231 2675 4231 
-Q 1875 4231 1450 3742 
-Q 1025 3253 1025 2328 
-Q 1025 1406 1450 917 
-Q 1875 428 2675 428 
-Q 3081 428 3442 575 
-Q 3803 722 4122 1019 
-L 4122 359 
-Q 3791 134 3420 21 
-Q 3050 -91 2638 -91 
-Q 1578 -91 968 557 
-Q 359 1206 359 2328 
-Q 359 3453 968 4101 
-Q 1578 4750 2638 4750 
-Q 3056 4750 3426 4639 
-Q 3797 4528 4122 4306 
+       <path id="DejaVuSans-49" d="M 628 4666 
+L 1259 4666 
+L 1259 0 
+L 628 0 
+L 628 4666 
+z
+" transform="scale(0.015625)"/>
+       <path id="DejaVuSans-52" d="M 2841 2188 
+Q 3044 2119 3236 1894 
+Q 3428 1669 3622 1275 
+L 4263 0 
+L 3584 0 
+L 2988 1197 
+Q 2756 1666 2539 1819 
+Q 2322 1972 1947 1972 
+L 1259 1972 
+L 1259 0 
+L 628 0 
+L 628 4666 
+L 2053 4666 
+Q 2853 4666 3247 4331 
+Q 3641 3997 3641 3322 
+Q 3641 2881 3436 2590 
+Q 3231 2300 2841 2188 
+z
+M 1259 4147 
+L 1259 2491 
+L 2053 2491 
+Q 2509 2491 2742 2702 
+Q 2975 2913 2975 3322 
+Q 2975 3731 2742 3939 
+Q 2509 4147 2053 4147 
+L 1259 4147 
 z
 " transform="scale(0.015625)"/>
        <path id="DejaVuSans-54" d="M -19 4666 
@@ -1156,12 +1140,12 @@ L -19 4666
 z
 " transform="scale(0.015625)"/>
       </defs>
-      <use xlink:href="#DejaVuSans-53"/>
-      <use xlink:href="#DejaVuSans-45" x="63.476562"/>
-      <use xlink:href="#DejaVuSans-4c" x="126.660156"/>
-      <use xlink:href="#DejaVuSans-45" x="182.373047"/>
-      <use xlink:href="#DejaVuSans-43" x="245.556641"/>
-      <use xlink:href="#DejaVuSans-54" x="315.380859"/>
+      <use xlink:href="#DejaVuSans-49"/>
+      <use xlink:href="#DejaVuSans-4e" x="29.492188"/>
+      <use xlink:href="#DejaVuSans-53" x="104.296875"/>
+      <use xlink:href="#DejaVuSans-45" x="167.773438"/>
+      <use xlink:href="#DejaVuSans-52" x="230.957031"/>
+      <use xlink:href="#DejaVuSans-54" x="293.189453"/>
      </g>
     </g>
     <g id="patch_19">
@@ -1172,10 +1156,31 @@ L 66.6 95.104813
 z
 " style="fill: #2ca02c"/>
     </g>
-    <g id="text_17">
+    <g id="text_16">
      <!-- COPY -->
      <g transform="translate(94.6 102.104813) scale(0.1 -0.1)">
       <defs>
+       <path id="DejaVuSans-43" d="M 4122 4306 
+L 4122 3641 
+Q 3803 3938 3442 4084 
+Q 3081 4231 2675 4231 
+Q 1875 4231 1450 3742 
+Q 1025 3253 1025 2328 
+Q 1025 1406 1450 917 
+Q 1875 428 2675 428 
+Q 3081 428 3442 575 
+Q 3803 722 4122 1019 
+L 4122 359 
+Q 3791 134 3420 21 
+Q 3050 -91 2638 -91 
+Q 1578 -91 968 557 
+Q 359 1206 359 2328 
+Q 359 3453 968 4101 
+Q 1578 4750 2638 4750 
+Q 3056 4750 3426 4639 
+Q 3797 4528 4122 4306 
+z
+" transform="scale(0.015625)"/>
        <path id="DejaVuSans-4f" d="M 2522 4238 
 Q 1834 4238 1429 3725 
 Q 1025 3213 1025 2328 
@@ -1241,7 +1246,7 @@ z
   </g>
  </g>
  <defs>
-  <clipPath id="pe972ace1b8">
+  <clipPath id="p1ecb086c24">
    <rect x="57.6" y="41.472" width="357.12" height="266.112"/>
   </clipPath>
  </defs>
diff --git a/benchmark/string/result.csv b/benchmark/string/result.csv
deleted file mode 100644
index 3a5a181..0000000
--- a/benchmark/string/result.csv
+++ /dev/null
@@ -1,10 +0,0 @@
-Approach,N records,Elapsed time (sec)
-Apache Arrow Flight SQL,100000,0.047
-SELECT,100000,0.017
-COPY,100000,0.017
-Apache Arrow Flight SQL,1000000,0.512
-SELECT,1000000,0.155
-COPY,1000000,0.153
-Apache Arrow Flight SQL,10000000,2.951
-SELECT,10000000,1.706
-COPY,10000000,1.640
diff --git a/benchmark/string/select.csv b/benchmark/string/select.csv
new file mode 100644
index 0000000..8053df9
--- /dev/null
+++ b/benchmark/string/select.csv
@@ -0,0 +1,10 @@
+Approach,N records,Elapsed time (sec)
+Apache Arrow Flight SQL,100000,0.041
+SELECT,100000,0.016
+COPY,100000,0.016
+Apache Arrow Flight SQL,1000000,0.353
+SELECT,1000000,0.149
+COPY,1000000,0.148
+Apache Arrow Flight SQL,10000000,2.154
+SELECT,10000000,1.924
+COPY,10000000,1.596
diff --git a/benchmark/string/result.svg b/benchmark/string/select.svg
similarity index 86%
rename from benchmark/string/result.svg
rename to benchmark/string/select.svg
index 590670f..e937061 100644
--- a/benchmark/string/result.svg
+++ b/benchmark/string/select.svg
@@ -6,7 +6,7 @@
   <rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/"; 
xmlns:cc="http://creativecommons.org/ns#"; 
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";>
    <cc:Work>
     <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:date>2023-11-13T18:19:08.495288</dc:date>
+    <dc:date>2023-11-16T18:51:20.134370</dc:date>
     <dc:format>image/svg+xml</dc:format>
     <dc:creator>
      <cc:Agent>
@@ -40,18 +40,18 @@ z
    <g id="patch_3">
     <path d="M 69.82144 307.584 
 L 100.93056 307.584 
-L 100.93056 303.547511 
-L 69.82144 303.547511 
+L 100.93056 302.759933 
+L 69.82144 302.759933 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #1f77b4"/>
+" clip-path="url(#p27f446f3c3)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_4">
     <path d="M 188.86144 307.584 
 L 219.97056 307.584 
-L 219.97056 263.612031 
-L 188.86144 263.612031 
+L 219.97056 266.049961 
+L 188.86144 266.049961 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #1f77b4"/>
+" clip-path="url(#p27f446f3c3)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_5">
     <path d="M 307.90144 307.584 
@@ -59,66 +59,66 @@ L 339.01056 307.584
 L 339.01056 54.144 
 L 307.90144 54.144 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #1f77b4"/>
+" clip-path="url(#p27f446f3c3)" style="fill: #1f77b4"/>
    </g>
    <g id="patch_6">
     <path d="M 101.56544 307.584 
 L 132.67456 307.584 
-L 132.67456 306.123993 
-L 101.56544 306.123993 
+L 132.67456 305.701437 
+L 101.56544 305.701437 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #ff7f0e"/>
+" clip-path="url(#p27f446f3c3)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_7">
     <path d="M 220.60544 307.584 
 L 251.71456 307.584 
-L 251.71456 294.272174 
-L 220.60544 294.272174 
+L 251.71456 290.052635 
+L 220.60544 290.052635 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #ff7f0e"/>
+" clip-path="url(#p27f446f3c3)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_8">
     <path d="M 339.64544 307.584 
 L 370.75456 307.584 
-L 370.75456 161.068026 
-L 339.64544 161.068026 
+L 370.75456 81.205838 
+L 339.64544 81.205838 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #ff7f0e"/>
+" clip-path="url(#p27f446f3c3)" style="fill: #ff7f0e"/>
    </g>
    <g id="patch_9">
     <path d="M 133.30944 307.584 
 L 164.41856 307.584 
-L 164.41856 306.123993 
-L 133.30944 306.123993 
+L 164.41856 305.701437 
+L 133.30944 305.701437 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #2ca02c"/>
+" clip-path="url(#p27f446f3c3)" style="fill: #2ca02c"/>
    </g>
    <g id="patch_10">
     <path d="M 252.34944 307.584 
 L 283.45856 307.584 
-L 283.45856 294.443939 
-L 252.34944 294.443939 
+L 283.45856 290.170295 
+L 252.34944 290.170295 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #2ca02c"/>
+" clip-path="url(#p27f446f3c3)" style="fill: #2ca02c"/>
    </g>
    <g id="patch_11">
     <path d="M 371.38944 307.584 
 L 402.49856 307.584 
-L 402.49856 166.736287 
-L 371.38944 166.736287 
+L 402.49856 119.798373 
+L 371.38944 119.798373 
 z
-" clip-path="url(#p3aca9fb4c4)" style="fill: #2ca02c"/>
+" clip-path="url(#p27f446f3c3)" style="fill: #2ca02c"/>
    </g>
    <g id="matplotlib.axis_1">
     <g id="xtick_1">
      <g id="line2d_1">
       <defs>
-       <path id="mc298820655" d="M 0 0 
+       <path id="m0e91be2c30" d="M 0 0 
 L 0 3.5 
 " style="stroke: #000000; stroke-width: 0.8"/>
       </defs>
       <g>
-       <use xlink:href="#mc298820655" x="117.12" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m0e91be2c30" x="117.12" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_1">
@@ -173,7 +173,7 @@ z
     <g id="xtick_2">
      <g id="line2d_2">
       <g>
-       <use xlink:href="#mc298820655" x="236.16" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m0e91be2c30" x="236.16" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_2">
@@ -192,7 +192,7 @@ z
     <g id="xtick_3">
      <g id="line2d_3">
       <g>
-       <use xlink:href="#mc298820655" x="355.2" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#m0e91be2c30" x="355.2" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_3">
@@ -385,12 +385,12 @@ z
     <g id="ytick_1">
      <g id="line2d_4">
       <defs>
-       <path id="m8afccf3ad6" d="M 0 0 
+       <path id="me5dc1668b5" d="M 0 0 
 L -3.5 0 
 " style="stroke: #000000; stroke-width: 0.8"/>
       </defs>
       <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#me5dc1668b5" x="57.6" y="307.584" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_5">
@@ -414,12 +414,12 @@ z
     <g id="ytick_2">
      <g id="line2d_5">
       <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="264.642624" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#me5dc1668b5" x="57.6" y="248.753916" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_6">
       <!-- 0.5 -->
-      <g transform="translate(34.696875 268.441843) scale(0.1 -0.1)">
+      <g transform="translate(34.696875 252.553135) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-35" d="M 691 4666 
 L 3169 4666 
@@ -456,12 +456,12 @@ z
     <g id="ytick_3">
      <g id="line2d_6">
       <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="221.701248" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#me5dc1668b5" x="57.6" y="189.923833" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_7">
       <!-- 1.0 -->
-      <g transform="translate(34.696875 225.500467) scale(0.1 -0.1)">
+      <g transform="translate(34.696875 193.723052) scale(0.1 -0.1)">
        <use xlink:href="#DejaVuSans-31"/>
        <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
        <use xlink:href="#DejaVuSans-30" x="95.410156"/>
@@ -471,12 +471,12 @@ z
     <g id="ytick_4">
      <g id="line2d_7">
       <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="178.759873" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#me5dc1668b5" x="57.6" y="131.093749" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_8">
       <!-- 1.5 -->
-      <g transform="translate(34.696875 182.559091) scale(0.1 -0.1)">
+      <g transform="translate(34.696875 134.892968) scale(0.1 -0.1)">
        <use xlink:href="#DejaVuSans-31"/>
        <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
        <use xlink:href="#DejaVuSans-35" x="95.410156"/>
@@ -486,12 +486,12 @@ z
     <g id="ytick_5">
      <g id="line2d_8">
       <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="135.818497" style="stroke: 
#000000; stroke-width: 0.8"/>
+       <use xlink:href="#me5dc1668b5" x="57.6" y="72.263666" style="stroke: 
#000000; stroke-width: 0.8"/>
       </g>
      </g>
      <g id="text_9">
       <!-- 2.0 -->
-      <g transform="translate(34.696875 139.617716) scale(0.1 -0.1)">
+      <g transform="translate(34.696875 76.062884) scale(0.1 -0.1)">
        <defs>
         <path id="DejaVuSans-32" d="M 1228 531 
 L 3431 531 
@@ -524,71 +524,7 @@ z
       </g>
      </g>
     </g>
-    <g id="ytick_6">
-     <g id="line2d_9">
-      <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="92.877121" style="stroke: 
#000000; stroke-width: 0.8"/>
-      </g>
-     </g>
-     <g id="text_10">
-      <!-- 2.5 -->
-      <g transform="translate(34.696875 96.67634) scale(0.1 -0.1)">
-       <use xlink:href="#DejaVuSans-32"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-35" x="95.410156"/>
-      </g>
-     </g>
-    </g>
-    <g id="ytick_7">
-     <g id="line2d_10">
-      <g>
-       <use xlink:href="#m8afccf3ad6" x="57.6" y="49.935745" style="stroke: 
#000000; stroke-width: 0.8"/>
-      </g>
-     </g>
-     <g id="text_11">
-      <!-- 3.0 -->
-      <g transform="translate(34.696875 53.734964) scale(0.1 -0.1)">
-       <defs>
-        <path id="DejaVuSans-33" d="M 2597 2516 
-Q 3050 2419 3304 2112 
-Q 3559 1806 3559 1356 
-Q 3559 666 3084 287 
-Q 2609 -91 1734 -91 
-Q 1441 -91 1130 -33 
-Q 819 25 488 141 
-L 488 750 
-Q 750 597 1062 519 
-Q 1375 441 1716 441 
-Q 2309 441 2620 675 
-Q 2931 909 2931 1356 
-Q 2931 1769 2642 2001 
-Q 2353 2234 1838 2234 
-L 1294 2234 
-L 1294 2753 
-L 1863 2753 
-Q 2328 2753 2575 2939 
-Q 2822 3125 2822 3475 
-Q 2822 3834 2567 4026 
-Q 2313 4219 1838 4219 
-Q 1578 4219 1281 4162 
-Q 984 4106 628 3988 
-L 628 4550 
-Q 988 4650 1302 4700 
-Q 1616 4750 1894 4750 
-Q 2613 4750 3031 4423 
-Q 3450 4097 3450 3541 
-Q 3450 3153 3228 2886 
-Q 3006 2619 2597 2516 
-z
-" transform="scale(0.015625)"/>
-       </defs>
-       <use xlink:href="#DejaVuSans-33"/>
-       <use xlink:href="#DejaVuSans-2e" x="63.623047"/>
-       <use xlink:href="#DejaVuSans-30" x="95.410156"/>
-      </g>
-     </g>
-    </g>
-    <g id="text_12">
+    <g id="text_10">
      <!-- Elapsed time (sec) -->
      <g transform="translate(28.617187 220.976438) rotate(-90) scale(0.1 
-0.1)">
       <defs>
@@ -785,32 +721,32 @@ z
      </g>
     </g>
    </g>
+   <g id="line2d_9">
+    <path clip-path="url(#p27f446f3c3)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+   </g>
+   <g id="line2d_10">
+    <path clip-path="url(#p27f446f3c3)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+   </g>
    <g id="line2d_11">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p27f446f3c3)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_12">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p27f446f3c3)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_13">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p27f446f3c3)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_14">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p27f446f3c3)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_15">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p27f446f3c3)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_16">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p27f446f3c3)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="line2d_17">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
-   </g>
-   <g id="line2d_18">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
-   </g>
-   <g id="line2d_19">
-    <path clip-path="url(#p3aca9fb4c4)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
+    <path clip-path="url(#p27f446f3c3)" style="fill: none; stroke: #424242; 
stroke-width: 2.7; stroke-linecap: square"/>
    </g>
    <g id="patch_12">
     <path d="M 57.6 307.584 
@@ -846,7 +782,7 @@ Q 62.6 108.1845 64.6 108.1845
 z
 " style="fill: #ffffff; opacity: 0.8; stroke: #cccccc; stroke-linejoin: 
miter"/>
     </g>
-    <g id="text_13">
+    <g id="text_11">
      <!-- Approach -->
      <g transform="translate(118.6 58.070438) scale(0.1 -0.1)">
       <defs>
@@ -904,7 +840,7 @@ L 66.6 65.748563
 z
 " style="fill: #1f77b4"/>
     </g>
-    <g id="text_14">
+    <g id="text_12">
      <!-- Apache Arrow Flight SQL -->
      <g transform="translate(94.6 72.748563) scale(0.1 -0.1)">
       <defs>
@@ -1071,7 +1007,7 @@ L 66.6 80.426688
 z
 " style="fill: #ff7f0e"/>
     </g>
-    <g id="text_15">
+    <g id="text_13">
      <!-- SELECT -->
      <g transform="translate(94.6 87.426688) scale(0.1 -0.1)">
       <defs>
@@ -1124,7 +1060,7 @@ L 66.6 95.104813
 z
 " style="fill: #2ca02c"/>
     </g>
-    <g id="text_16">
+    <g id="text_14">
      <!-- COPY -->
      <g transform="translate(94.6 102.104813) scale(0.1 -0.1)">
       <defs>
@@ -1193,7 +1129,7 @@ z
   </g>
  </g>
  <defs>
-  <clipPath id="p3aca9fb4c4">
+  <clipPath id="p27f446f3c3">
    <rect x="57.6" y="41.472" width="357.12" height="266.112"/>
   </clipPath>
  </defs>
diff --git a/dev/release/rat_exclude_files.txt 
b/dev/release/rat_exclude_files.txt
index 61c7482..101343b 100644
--- a/dev/release/rat_exclude_files.txt
+++ b/dev/release/rat_exclude_files.txt
@@ -15,8 +15,8 @@
 # specific language governing permissions and limitations
 # under the License.
 
-benchmark/*/result.csv
-benchmark/*/result.svg
+benchmark/*/*.csv
+benchmark/*/*.svg
 compile_commands.json
 dev/release/apache-rat-*.jar
 dev/release/filtered_rat.txt
diff --git a/src/afs.cc b/src/afs.cc
index 23940b9..867596c 100644
--- a/src/afs.cc
+++ b/src/afs.cc
@@ -1493,10 +1493,6 @@ class Executor : public WorkerProcessor {
                                // TODO: Customizable.
                                SharedRingBuffer::allocate_data(
                                        &(session->bufferData), area_, 1L * 
1024L * 1024L);
-
-                               SetCurrentStatementStartTimestamp();
-                               SPI_connect();
-                               needFinish_ = true;
                        }
                        session->initialized = true;
                        localSession_->valid = true;
@@ -1884,8 +1880,9 @@ class Executor : public WorkerProcessor {
                        ScopedSnapshot scopedSnapshot;
 
                        SetCurrentStatementStartTimestamp();
-                       auto result = SPI_execute(query.c_str(), true, 0);
+                       SPI_connect();
                        needFinish_ = true;
+                       auto result = SPI_execute(query.c_str(), true, 0);
                        if (result > 0)
                        {
                                pgstat_report_activity(
@@ -2059,8 +2056,9 @@ class Executor : public WorkerProcessor {
                        ScopedSnapshot scopedSnapshot;
 
                        SetCurrentStatementStartTimestamp();
-                       auto result = SPI_execute(query.c_str(), false, 0);
+                       SPI_connect();
                        needFinish_ = true;
+                       auto result = SPI_execute(query.c_str(), false, 0);
                        if (result > 0)
                        {
                                session->nUpdatedRecords = SPI_processed;
@@ -2237,6 +2235,9 @@ class Executor : public WorkerProcessor {
                ScopedTransaction scopedTransaction;
                ScopedSnapshot scopedSnapshot;
 
+               SetCurrentStatementStartTimestamp();
+               SPI_connect();
+               needFinish_ = true;
                struct Data {
                        Executor* executor;
                        const char* tag;
@@ -2247,7 +2248,6 @@ class Executor : public WorkerProcessor {
                                return 
d->executor->write_record_batches(d->tag);
                        },
                        &data);
-               needFinish_ = true;
                if (!status.ok())
                {
                        set_error_message(session,
@@ -2282,9 +2282,11 @@ class Executor : public WorkerProcessor {
                ScopedTransaction scopedTransaction;
                ScopedSnapshot scopedSnapshot;
 
+               SetCurrentStatementStartTimestamp();
+               SPI_connect();
+               needFinish_ = true;
                auto input = 
std::make_shared<SharedRingBufferInputStream>(this, localSession_);
                auto n_updated_records_result = 
preparedStatement->update(input);
-               needFinish_ = true;
                if (n_updated_records_result.ok())
                {
                        session->nUpdatedRecords = *n_updated_records_result;


Reply via email to