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.git
The following commit(s) were added to refs/heads/main by this push:
new 797f3460c1 GH-35316: [C++][FlightSQL] Use RowsToBatches() instead of
ArrayFromJSON() in SQLite example server (#35322)
797f3460c1 is described below
commit 797f3460c15d11f3e5b12da1809644e53fd910b5
Author: Sutou Kouhei <[email protected]>
AuthorDate: Wed Apr 26 11:31:18 2023 +0900
GH-35316: [C++][FlightSQL] Use RowsToBatches() instead of ArrayFromJSON()
in SQLite example server (#35322)
### Rationale for this change
`ArrayFromJSON()` requires `libarrow_testing.so`. But
`cpp/examples/arrow/flight_sql_example.cc` uses the SQLite example server
without `libarrow_testing.so` dependency.
### What changes are included in this PR?
Use `RowsToBatches()` in `libarrow.so` instead of `ArrayFromJSON()`.
### Are these changes tested?
Yes by hand.
### Are there any user-facing changes?
Yes.
* Closes: #35316
Authored-by: Sutou Kouhei <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
---
cpp/src/arrow/flight/sql/example/sqlite_server.cc | 7 +-
.../arrow/flight/sql/example/sqlite_type_info.cc | 222 +++++++++++++++------
.../arrow/flight/sql/example/sqlite_type_info.h | 4 +-
cpp/src/arrow/flight/sql/server_test.cc | 4 +-
4 files changed, 174 insertions(+), 63 deletions(-)
diff --git a/cpp/src/arrow/flight/sql/example/sqlite_server.cc
b/cpp/src/arrow/flight/sql/example/sqlite_server.cc
index a02f825a9e..9a80dd56f1 100644
--- a/cpp/src/arrow/flight/sql/example/sqlite_server.cc
+++ b/cpp/src/arrow/flight/sql/example/sqlite_server.cc
@@ -573,9 +573,10 @@ class SQLiteFlightSqlServer::Impl {
arrow::Result<std::unique_ptr<FlightDataStream>> DoGetTypeInfo(
const ServerCallContext& context, const GetXdbcTypeInfo& command) {
- const std::shared_ptr<RecordBatch>& type_info_result =
- command.data_type.has_value() ?
DoGetTypeInfoResult(command.data_type.value())
- : DoGetTypeInfoResult();
+ ARROW_ASSIGN_OR_RAISE(auto type_info_result,
+ command.data_type.has_value()
+ ? DoGetTypeInfoResult(command.data_type.value())
+ : DoGetTypeInfoResult());
ARROW_ASSIGN_OR_RAISE(auto reader,
RecordBatchReader::Make({type_info_result}));
return std::make_unique<RecordBatchStream>(reader);
diff --git a/cpp/src/arrow/flight/sql/example/sqlite_type_info.cc
b/cpp/src/arrow/flight/sql/example/sqlite_type_info.cc
index 3c5bf2fc5d..9cb59b7dc1 100644
--- a/cpp/src/arrow/flight/sql/example/sqlite_type_info.cc
+++ b/cpp/src/arrow/flight/sql/example/sqlite_type_info.cc
@@ -17,74 +17,184 @@
#include "arrow/flight/sql/example/sqlite_type_info.h"
+#include "arrow/array/builder_binary.h"
+#include "arrow/array/builder_nested.h"
+#include "arrow/array/builder_primitive.h"
#include "arrow/flight/sql/server.h"
#include "arrow/flight/sql/types.h"
#include "arrow/record_batch.h"
-#include "arrow/testing/gtest_util.h"
+#include "arrow/util/rows_to_batches.h"
namespace arrow {
namespace flight {
namespace sql {
namespace example {
-std::shared_ptr<RecordBatch> DoGetTypeInfoResult() {
- auto type_name_array =
- ArrayFromJSON(utf8(), R"(["bit", "tinyint", "bigint", "longvarbinary",
- "varbinary", "text", "longvarchar", "char",
- "integer", "smallint", "float", "double",
- "numeric", "varchar", "date", "time",
- "timestamp"])");
- auto data_type = ArrayFromJSON(
- int32(), R"([-7, -6, -5, -4, -3, -1, -1, 1, 4, 5, 6, 8, 8, 12, 91, 92,
93])");
- auto column_size = ArrayFromJSON(
- int32(),
- R"([1, 3, 19, 65536, 255, 65536, 65536, 255, 9, 5, 7, 15, 15, 255, 10,
8, 32])");
- auto literal_prefix = ArrayFromJSON(
- utf8(),
- R"([null, null, null, null, null, "'", "'", "'", null, null, null, null,
null, "'", "'", "'", "'"])");
- auto literal_suffix = ArrayFromJSON(
- utf8(),
- R"([null, null, null, null, null, "'", "'", "'", null, null, null, null,
null, "'", "'", "'", "'"])");
- auto create_params = ArrayFromJSON(
- list(field("item", utf8(), false)),
- R"([[], [], [], [], [], ["length"], ["length"], ["length"], [], [], [],
[], [], ["length"], [], [], []])");
- auto nullable =
- ArrayFromJSON(int32(), R"([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1])");
- // Reference for creating a boolean() array only with zero.
- auto zero_bool_array =
- ArrayFromJSON(boolean(), R"([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0])");
- const auto& case_sensitive = zero_bool_array;
- auto searchable =
- ArrayFromJSON(int32(), R"([3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3])");
- const auto& unsigned_attribute = zero_bool_array;
- const auto& fixed_prec_scale = zero_bool_array;
- const auto& auto_unique_value = zero_bool_array;
- auto local_type_name =
- ArrayFromJSON(utf8(), R"(["bit", "tinyint", "bigint", "longvarbinary",
- "varbinary", "text", "longvarchar", "char",
- "integer", "smallint", "float", "double",
- "numeric", "varchar", "date", "time",
- "timestamp"])");
- // Reference for creating an int32() array only with zero.
- auto zero_int_array =
- ArrayFromJSON(int32(), R"([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0])");
- const auto& minimal_scale = zero_int_array;
- const auto& maximum_scale = zero_int_array;
- const auto& sql_data_type = data_type;
- const auto& sql_datetime_sub = zero_int_array;
- const auto& num_prec_radix = zero_int_array;
- const auto& interval_precision = zero_int_array;
+arrow::Result<std::shared_ptr<RecordBatch>> DoGetTypeInfoResult() {
+ auto schema = SqlSchema::GetXdbcTypeInfoSchema();
+ using ValueType =
+ std::variant<bool, int32_t, std::nullptr_t, const char*,
std::vector<const char*>>;
+ auto VariantConverter = [](ArrayBuilder& array_builder, const ValueType&
value) {
+ if (std::holds_alternative<bool>(value)) {
+ return
dynamic_cast<BooleanBuilder&>(array_builder).Append(std::get<bool>(value));
+ } else if (std::holds_alternative<int32_t>(value)) {
+ return
dynamic_cast<Int32Builder&>(array_builder).Append(std::get<int32_t>(value));
+ } else if (std::holds_alternative<std::nullptr_t>(value)) {
+ return array_builder.AppendNull();
+ } else if (std::holds_alternative<const char*>(value)) {
+ return dynamic_cast<StringBuilder&>(array_builder)
+ .Append(std::get<const char*>(value));
+ } else {
+ auto& list_builder = dynamic_cast<ListBuilder&>(array_builder);
+ ARROW_RETURN_NOT_OK(list_builder.Append());
+ auto value_builder =
dynamic_cast<StringBuilder*>(list_builder.value_builder());
+ for (const auto& v : std::get<std::vector<const char*>>(value)) {
+ ARROW_RETURN_NOT_OK(value_builder->Append(v));
+ }
+ return Status::OK();
+ }
+ };
+ std::vector<std::vector<ValueType>> rows = {
+ {
+ "bit", -7, 1, nullptr, nullptr, std::vector<const char*>({}),
+ 1, false, 3, false, false, false,
+ "bit", 0, 0, -7, 0, 0,
+ 0,
+ },
+ {
+ "tinyint", -6, 3, nullptr, nullptr, std::vector<const char*>({}),
+ 1, false, 3, false, false, false,
+ "tinyint", 0, 0, -6, 0, 0,
+ 0,
+ },
+ {
+ "bigint", -5, 19, nullptr, nullptr, std::vector<const char*>({}),
+ 1, false, 3, false, false, false,
+ "bigint", 0, 0, -5, 0, 0,
+ 0,
+ },
+ {
+ "longvarbinary",
+ -4,
+ 65536,
+ nullptr,
+ nullptr,
+ std::vector<const char*>({}),
+ 1,
+ false,
+ 3,
+ false,
+ false,
+ false,
+ "longvarbinary",
+ 0,
+ 0,
+ -4,
+ 0,
+ 0,
+ 0,
+ },
+ {
+ "varbinary", -3, 255, nullptr, nullptr, std::vector<const
char*>({}),
+ 1, false, 3, false, false, false,
- return RecordBatch::Make(
- SqlSchema::GetXdbcTypeInfoSchema(), 17,
- {type_name_array, data_type, column_size, literal_prefix, literal_suffix,
- create_params, nullable, case_sensitive, searchable, unsigned_attribute,
- fixed_prec_scale, auto_unique_value, local_type_name, minimal_scale,
maximum_scale,
- sql_data_type, sql_datetime_sub, num_prec_radix, interval_precision});
+ "varbinary", 0, 0, -3, 0, 0,
+ 0,
+ },
+ {
+ "text", -1, 65536, "'", "'", std::vector<const
char*>({"length"}),
+ 1, false, 3, false, false, false,
+ "text", 0, 0, -1, 0, 0,
+ 0,
+ },
+ {
+ "longvarchar",
+ -1,
+ 65536,
+ "'",
+ "'",
+ std::vector<const char*>({"length"}),
+ 1,
+ false,
+ 3,
+ false,
+ false,
+ false,
+ "longvarchar",
+ 0,
+ 0,
+ -1,
+ 0,
+ 0,
+ 0,
+ },
+ {
+ "char", 1, 255, "'", "'", std::vector<const
char*>({"length"}),
+ 1, false, 3, false, false, false,
+ "char", 0, 0, 1, 0, 0,
+ 0,
+ },
+ {
+ "integer", 4, 9, nullptr, nullptr, std::vector<const char*>({}),
+ 1, false, 3, false, false, false,
+ "integer", 0, 0, 4, 0, 0,
+ 0,
+ },
+ {
+ "smallint", 5, 5, nullptr, nullptr, std::vector<const char*>({}),
+ 1, false, 3, false, false, false,
+ "smallint", 0, 0, 5, 0, 0,
+ 0,
+ },
+ {
+ "float", 6, 7, nullptr, nullptr, std::vector<const char*>({}),
+ 1, false, 3, false, false, false,
+ "float", 0, 0, 6, 0, 0,
+ 0,
+ },
+ {
+ "double", 8, 15, nullptr, nullptr, std::vector<const char*>({}),
+ 1, false, 3, false, false, false,
+ "double", 0, 0, 8, 0, 0,
+ 0,
+ },
+ {
+ "numeric", 8, 15, nullptr, nullptr, std::vector<const char*>({}),
+ 1, false, 3, false, false, false,
+ "numeric", 0, 0, 8, 0, 0,
+ 0,
+ },
+ {
+ "varchar", 12, 255, "'", "'", std::vector<const
char*>({"length"}),
+ 1, false, 3, false, false, false,
+ "varchar", 0, 0, 12, 0, 0,
+ 0,
+ },
+ {
+ "date", 91, 10, "'", "'", std::vector<const char*>({}),
+ 1, false, 3, false, false, false,
+ "date", 0, 0, 91, 0, 0,
+ 0,
+ },
+ {
+ "time", 92, 8, "'", "'", std::vector<const char*>({}),
+ 1, false, 3, false, false, false,
+ "time", 0, 0, 92, 0, 0,
+ 0,
+ },
+ {
+ "timestamp", 93, 32, "'", "'", std::vector<const char*>({}),
+ 1, false, 3, false, false, false,
+ "timestamp", 0, 0, 93, 0, 0,
+ 0,
+ },
+ };
+ ARROW_ASSIGN_OR_RAISE(auto reader, RowsToBatches(schema, rows,
VariantConverter));
+ return reader->Next();
}
-std::shared_ptr<RecordBatch> DoGetTypeInfoResult(int data_type_filter) {
- auto record_batch = DoGetTypeInfoResult();
+arrow::Result<std::shared_ptr<RecordBatch>> DoGetTypeInfoResult(int
data_type_filter) {
+ ARROW_ASSIGN_OR_RAISE(auto record_batch, DoGetTypeInfoResult());
std::vector<int> data_type_vector{-7, -6, -5, -4, -3, -1, -1, 1, 4,
5, 6, 8, 8, 12, 91, 92, 93};
diff --git a/cpp/src/arrow/flight/sql/example/sqlite_type_info.h
b/cpp/src/arrow/flight/sql/example/sqlite_type_info.h
index a2c095f4c6..a104626c0f 100644
--- a/cpp/src/arrow/flight/sql/example/sqlite_type_info.h
+++ b/cpp/src/arrow/flight/sql/example/sqlite_type_info.h
@@ -26,12 +26,12 @@ namespace example {
/// \brief Gets the harded-coded type info from Sqlite for all data types.
/// \return A record batch.
-std::shared_ptr<RecordBatch> DoGetTypeInfoResult();
+arrow::Result<std::shared_ptr<RecordBatch>> DoGetTypeInfoResult();
/// \brief Gets the harded-coded type info from Sqlite filtering
/// for a specific data type.
/// \return A record batch.
-std::shared_ptr<RecordBatch> DoGetTypeInfoResult(int data_type_filter);
+arrow::Result<std::shared_ptr<RecordBatch>> DoGetTypeInfoResult(int
data_type_filter);
} // namespace example
} // namespace sql
} // namespace flight
diff --git a/cpp/src/arrow/flight/sql/server_test.cc
b/cpp/src/arrow/flight/sql/server_test.cc
index 0eedbda303..cdefd9c179 100644
--- a/cpp/src/arrow/flight/sql/server_test.cc
+++ b/cpp/src/arrow/flight/sql/server_test.cc
@@ -363,7 +363,7 @@ TEST_F(TestFlightSqlServer, TestCommandGetTypeInfo) {
ASSERT_OK_AND_ASSIGN(auto stream,
sql_client->DoGet({},
flight_info->endpoints()[0].ticket));
- auto batch = example::DoGetTypeInfoResult();
+ ASSERT_OK_AND_ASSIGN(auto batch, example::DoGetTypeInfoResult());
ASSERT_OK_AND_ASSIGN(auto expected_table, Table::FromRecordBatches({batch}));
ASSERT_OK_AND_ASSIGN(auto table, stream->ToTable());
@@ -378,7 +378,7 @@ TEST_F(TestFlightSqlServer,
TestCommandGetTypeInfoWithFiltering) {
ASSERT_OK_AND_ASSIGN(auto stream,
sql_client->DoGet({},
flight_info->endpoints()[0].ticket));
- auto batch = example::DoGetTypeInfoResult(data_type);
+ ASSERT_OK_AND_ASSIGN(auto batch, example::DoGetTypeInfoResult(data_type));
ASSERT_OK_AND_ASSIGN(auto expected_table, Table::FromRecordBatches({batch}));
ASSERT_OK_AND_ASSIGN(auto table, stream->ToTable());