Skip to content

Commit

Permalink
apacheGH-35316: [C++][FlightSQL] Use RowsToBatches() instead of Array…
Browse files Browse the repository at this point in the history
…FromJSON() in SQLite example server (apache#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: apache#35316

Authored-by: Sutou Kouhei <kou@clear-code.com>
Signed-off-by: Sutou Kouhei <kou@clear-code.com>
  • Loading branch information
kou authored and ArgusLi committed May 15, 2023
1 parent e6bbac2 commit b0a43c2
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 63 deletions.
7 changes: 4 additions & 3 deletions cpp/src/arrow/flight/sql/example/sqlite_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
222 changes: 166 additions & 56 deletions cpp/src/arrow/flight/sql/example/sqlite_type_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
4 changes: 2 additions & 2 deletions cpp/src/arrow/flight/sql/example/sqlite_type_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions cpp/src/arrow/flight/sql/server_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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());
Expand Down

0 comments on commit b0a43c2

Please sign in to comment.