Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7351c63
Fix typo and checkstyle on FlightSql.proto
jcralmeida Dec 20, 2021
7dba990
Implement logic of column metadata
jcralmeida Dec 20, 2021
53222af
Revert change from SqlInfo commentary
jcralmeida Dec 20, 2021
2e564be
Improve documentation of the column metadata
jcralmeida Dec 20, 2021
bdb3a24
Add namespace to column metadata and make changes to prevent mutable …
jcralmeida Dec 20, 2021
8664a31
Implement column metadata on flight sql cpp module
jcralmeida Dec 20, 2021
d59a2c1
Improve documentation of protobuf and add namespace to metadata names
jcralmeida Dec 20, 2021
9534729
Move anonymous namespace inside the arrow:flight:sql namespaces
jcralmeida Jan 10, 2022
b172c92
Rename const variables and set getter methods as const
jcralmeida Jan 10, 2022
a65f49c
Change string boolean values from YES/NO to 1/0
jcralmeida Jan 11, 2022
656f0b6
Inline return of the ColumnMetadataBuilder
jcralmeida Jan 11, 2022
15541a0
Make getter of metadata_map as const and adjust code style
jcralmeida Jan 11, 2022
69d7e6c
Explicit declare variable as private and move it to the of file
jcralmeida Jan 11, 2022
a8d796a
Refactor of metadata_map getter in the code
jcralmeida Jan 11, 2022
fa97c69
Change name of parameter to be more consistency in booleanToString
jcralmeida Jan 11, 2022
5b04fbd
Format files from flight-sql in cpp
jcralmeida Jan 11, 2022
886f777
Inline assign of precision values from column metadata
jcralmeida Jan 11, 2022
d698e1d
Nit: extra space on GetPrecision method
jcralmeida Jan 11, 2022
fa3b1a3
Add column metadata to integration test on flight sql
jcralmeida Jan 12, 2022
19ce860
Fix code style
jcralmeida Jan 12, 2022
d34c081
Fix documentation of SQL_SUPPORTED_SUBQUERIES enum in FlightSql.proto
jcralmeida Mar 15, 2022
e0948df
Improve documentation of ARROW:FLIGHT:SQL:SCALE in FlightSql.proto
jcralmeida Mar 15, 2022
297df6b
Fix cases from params to snake_case in column_metadata.h
jcralmeida Mar 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions cpp/src/arrow/flight/sql/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ set_source_files_properties(${FLIGHT_SQL_GENERATED_PROTO_FILES} PROPERTIES GENER

add_custom_target(flight_sql_protobuf_gen ALL DEPENDS ${FLIGHT_SQL_GENERATED_PROTO_FILES})

set(ARROW_FLIGHT_SQL_SRCS server.cc sql_info_internal.cc client.cc
"${CMAKE_CURRENT_BINARY_DIR}/FlightSql.pb.cc")
set(ARROW_FLIGHT_SQL_SRCS
server.cc
sql_info_internal.cc
column_metadata.cc
client.cc
"${CMAKE_CURRENT_BINARY_DIR}/FlightSql.pb.cc")

add_arrow_lib(arrow_flight_sql
CMAKE_PACKAGE_NAME
Expand Down
187 changes: 187 additions & 0 deletions cpp/src/arrow/flight/sql/column_metadata.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
// 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 "arrow/flight/sql/column_metadata.h"

#include <utility>

namespace arrow {
namespace flight {
namespace sql {
namespace {
/// \brief Constant variable used to convert boolean true value
/// to a string.
const char* BOOLEAN_TRUE_STR = "YES";
/// \brief Constant variable used to convert boolean false value
/// to a string.
const char* BOOLEAN_FALSE_STR = "NO";

std::string BooleanToString(bool boolean_value) {
return boolean_value ? BOOLEAN_TRUE_STR :
BOOLEAN_FALSE_STR;
}

bool StringToBoolean(const std::string& string_value) {
return string_value == BOOLEAN_TRUE_STR;
}
} // namespace

const char* ColumnMetadata::kCatalogName = "ARROW:FLIGHT:SQL:CATALOG_NAME";
const char* ColumnMetadata::kSchemaName = "ARROW:FLIGHT:SQL:SCHEMA_NAME";
const char* ColumnMetadata::kTableName = "ARROW:FLIGHT:SQL:TABLE_NAME";
const char* ColumnMetadata::kPrecision = "ARROW:FLIGHT:SQL:PRECISION";
const char* ColumnMetadata::kScale = "ARROW:FLIGHT:SQL:SCALE";
const char* ColumnMetadata::kIsAutoIncrement = "ARROW:FLIGHT:SQL:IS_AUTO_INCREMENT";
const char* ColumnMetadata::kIsCaseSensitive = "ARROW:FLIGHT:SQL:IS_CASE_SENSITIVE";
const char* ColumnMetadata::kIsReadOnly = "ARROW:FLIGHT:SQL:IS_READ_ONLY";
const char* ColumnMetadata::kIsSearchable = "ARROW:FLIGHT:SQL:IS_SEARCHABLE";

ColumnMetadata::ColumnMetadata(std::shared_ptr<arrow::KeyValueMetadata> metadata_map) :
metadata_map_(std::move(metadata_map)) {
}

arrow::Result<std::string> ColumnMetadata::GetCatalogName() const {
return metadata_map_->Get(kCatalogName);
}

arrow::Result<std::string> ColumnMetadata::GetSchemaName() const {
return metadata_map_->Get(kSchemaName);
}

arrow::Result<std::string> ColumnMetadata::GetTableName() const {
return metadata_map_->Get(kTableName);
}

arrow::Result<int32_t> ColumnMetadata::GetPrecision() const {
const Result <std::string> &result = metadata_map_->Get(kPrecision);
Comment thread
jcralmeida marked this conversation as resolved.
Outdated
std::string precision_string;
ARROW_ASSIGN_OR_RAISE(precision_string, result);

return std::stoi(precision_string);
}

arrow::Result<int32_t> ColumnMetadata::GetScale() const {
std::string scale_string;
ARROW_ASSIGN_OR_RAISE(scale_string, metadata_map_->Get(kScale));

return std::stoi(scale_string);
}

arrow::Result<bool> ColumnMetadata::GetIsAutoIncrement() const {
std::string auto_increment_string;
ARROW_ASSIGN_OR_RAISE(auto_increment_string, metadata_map_->Get(kIsAutoIncrement));
return StringToBoolean(auto_increment_string);
}

arrow::Result<bool> ColumnMetadata::GetIsCaseSensitive() const {
std::string is_case_sensitive;
ARROW_ASSIGN_OR_RAISE(is_case_sensitive, metadata_map_->Get(kIsAutoIncrement));
return StringToBoolean(is_case_sensitive);
}

arrow::Result<bool> ColumnMetadata::GetIsReadOnly() const {
std::string is_read_only;
ARROW_ASSIGN_OR_RAISE(is_read_only, metadata_map_->Get(kIsAutoIncrement));
return StringToBoolean(is_read_only);
}

arrow::Result<bool> ColumnMetadata::GetIsSearchable() const {
std::string is_case_sensitive;
ARROW_ASSIGN_OR_RAISE(is_case_sensitive, metadata_map_->Get(kIsAutoIncrement));
return StringToBoolean(is_case_sensitive);
}

ColumnMetadata::ColumnMetadataBuilder ColumnMetadata::Builder() {
const ColumnMetadataBuilder &builder = ColumnMetadataBuilder{};
return builder;
Comment thread
jcralmeida marked this conversation as resolved.
Outdated
}

std::shared_ptr<arrow::KeyValueMetadata> ColumnMetadata::GetMetadataMap() const {
return metadata_map_;
}

ColumnMetadata::ColumnMetadataBuilder
&ColumnMetadata::ColumnMetadataBuilder::CatalogName(std::string &catalog_name) {
metadata_map_->Append(ColumnMetadata::kCatalogName, catalog_name);
return *this;
}


ColumnMetadata::ColumnMetadataBuilder
&ColumnMetadata::ColumnMetadataBuilder::SchemaName(std::string &schema_name) {
metadata_map_->Append(ColumnMetadata::kSchemaName, schema_name);
return *this;
}

ColumnMetadata::ColumnMetadataBuilder
&ColumnMetadata::ColumnMetadataBuilder::TableName(std::string &table_name) {
metadata_map_->Append(ColumnMetadata::kTableName, table_name);
return *this;
}

ColumnMetadata::ColumnMetadataBuilder
&ColumnMetadata::ColumnMetadataBuilder::Precision(int32_t precision) {
metadata_map_->Append(
ColumnMetadata::kPrecision, std::to_string(precision));
return *this;
}

ColumnMetadata::ColumnMetadataBuilder
&ColumnMetadata::ColumnMetadataBuilder::Scale(int32_t scale) {
metadata_map_->Append(
ColumnMetadata::kScale, std::to_string(scale));
return *this;
}

ColumnMetadata::ColumnMetadataBuilder &
ColumnMetadata::ColumnMetadataBuilder::IsAutoIncrement(bool is_auto_increment) {
metadata_map_->Append(ColumnMetadata::kIsAutoIncrement,
BooleanToString(is_auto_increment));
return *this;
}

ColumnMetadata::ColumnMetadataBuilder &
ColumnMetadata::ColumnMetadataBuilder::IsCaseSensitive(bool is_case_sensitive) {
metadata_map_->Append(ColumnMetadata::kIsCaseSensitive,
BooleanToString(is_case_sensitive));
return *this;
}

ColumnMetadata::ColumnMetadataBuilder
&ColumnMetadata::ColumnMetadataBuilder::IsReadOnly(bool is_read_only) {
metadata_map_->Append(ColumnMetadata::kIsReadOnly,
BooleanToString(is_read_only));
return *this;
}

ColumnMetadata::ColumnMetadataBuilder
&ColumnMetadata::ColumnMetadataBuilder::IsSearchable(bool is_searchable) {
metadata_map_->Append(ColumnMetadata::kIsSearchable,
BooleanToString(is_searchable));
return *this;
}

ColumnMetadata::ColumnMetadataBuilder::ColumnMetadataBuilder() : metadata_map_(
std::make_shared<arrow::KeyValueMetadata>()) {
}

ColumnMetadata ColumnMetadata::ColumnMetadataBuilder::Build() const {
return ColumnMetadata{metadata_map_};
}
} // namespace sql
} // namespace flight
} // namespace arrow
168 changes: 168 additions & 0 deletions cpp/src/arrow/flight/sql/column_metadata.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// 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.

#pragma once

#include <string>

#include "arrow/util/key_value_metadata.h"

namespace arrow {
namespace flight {
namespace sql {

/// \brief Helper class to set column metadata.
class ColumnMetadata {
private:
std::shared_ptr<arrow::KeyValueMetadata> metadata_map_;
explicit ColumnMetadata(std::shared_ptr<arrow::KeyValueMetadata> metadata_map);

public:
class ColumnMetadataBuilder;

/// \brief Constant variable to hold the value of the key that
/// will be used in the KeyValueMetadata class.
static const char* kCatalogName;
/// \brief Constant variable to hold the value of the key that
/// will be used in the KeyValueMetadata class.
static const char* kSchemaName;
/// \brief Constant variable to hold the value of the key that
/// will be used in the KeyValueMetadata class.
static const char* kTableName;
/// \brief Constant variable to hold the value of the key that
/// will be used in the KeyValueMetadata class.
static const char* kPrecision;
/// \brief Constant variable to hold the value of the key that
/// will be used in the KeyValueMetadata class.
static const char* kScale;
/// \brief Constant variable to hold the value of the key that
/// will be used in the KeyValueMetadata class.
static const char* kIsAutoIncrement;
/// \brief Constant variable to hold the value of the key that
/// will be used in the KeyValueMetadata class.
static const char* kIsCaseSensitive;
/// \brief Constant variable to hold the value of the key that
/// will be used in the KeyValueMetadata class.
static const char* kIsReadOnly;
/// \brief Constant variable to hold the value of the key that
/// will be used in the KeyValueMetadata class.
static const char* kIsSearchable;

/// \brief Static initializer.
static ColumnMetadataBuilder Builder();

/// \brief Return the catalog name set in the KeyValueMetadata.
/// \return The catalog name.
arrow::Result<std::string> GetCatalogName() const;

/// \brief Return the schema name set in the KeyValueMetadata.
/// \return The schema name.
arrow::Result<std::string> GetSchemaName() const;

/// \brief Return the table name set in the KeyValueMetadata.
/// \return The table name.
arrow::Result<std::string> GetTableName() const;

/// \brief Return the precision set in the KeyValueMetadata.
/// \return The precision.
arrow::Result<int32_t> GetPrecision() const;

/// \brief Return the scale set in the KeyValueMetadata.
/// \return The scale.
arrow::Result<int32_t> GetScale() const;

/// \brief Return the IsAutoIncrement set in the KeyValueMetadata.
/// \return The IsAutoIncrement.
arrow::Result<bool> GetIsAutoIncrement() const;

/// \brief Return the IsCaseSensitive set in the KeyValueMetadata.
/// \return The IsCaseSensitive.
arrow::Result<bool> GetIsCaseSensitive() const;

/// \brief Return the IsReadOnly set in the KeyValueMetadata.
/// \return The IsReadOnly.
arrow::Result<bool> GetIsReadOnly() const;

/// \brief Return the IsSearchable set in the KeyValueMetadata.
/// \return The IsSearchable.
arrow::Result<bool> GetIsSearchable() const;

/// \brief Return the KeyValueMetadata.
/// \return The KeyValueMetadata.
std::shared_ptr<arrow::KeyValueMetadata> GetMetadataMap() const;
Comment thread
jcralmeida marked this conversation as resolved.
Outdated

/// \brief A builder class to construct the ColumnMetadata object.
class ColumnMetadataBuilder {
std::shared_ptr<arrow::KeyValueMetadata> metadata_map_;
Comment thread
jcralmeida marked this conversation as resolved.
Outdated

/// \brief Default constructor.
ColumnMetadataBuilder();

public:
friend class ColumnMetadata;

/// \brief Set the catalog name in the KeyValueMetadata object.
/// \param[in] catalog_name The catalog name.
/// \return A ColumnMetadataBuilder.
ColumnMetadataBuilder& CatalogName(std::string &catalog_name);

/// \brief Set the schema_name in the KeyValueMetadata object.
/// \param[in] schema_name The schema_name.
/// \return A ColumnMetadataBuilder.
ColumnMetadataBuilder& SchemaName(std::string& schema_name);

/// \brief Set the table name in the KeyValueMetadata object.
/// \param[in] table_name The table name.
/// \return A ColumnMetadataBuilder.
ColumnMetadataBuilder& TableName(std::string& table_name);

/// \brief Set the precision in the KeyValueMetadata object.
/// \param[in] precision The precision.
/// \return A ColumnMetadataBuilder.
ColumnMetadataBuilder& Precision(int32_t precision);

/// \brief Set the scale in the KeyValueMetadata object.
/// \param[in] scale The scale.
/// \return A ColumnMetadataBuilder.
ColumnMetadataBuilder& Scale(int32_t scale);

/// \brief Set the IsAutoIncrement in the KeyValueMetadata object.
/// \param[in] IsAutoIncrement The IsAutoIncrement.
/// \return A ColumnMetadataBuilder.
ColumnMetadataBuilder& IsAutoIncrement(bool is_auto_increment);

/// \brief Set the IsCaseSensitive in the KeyValueMetadata object.
/// \param[in] IsCaseSensitive The IsCaseSensitive.
/// \return A ColumnMetadataBuilder.
ColumnMetadataBuilder& IsCaseSensitive(bool is_case_sensitive);

/// \brief Set the IsReadOnly in the KeyValueMetadata object.
/// \param[in] IsReadOnly The IsReadOnly.
/// \return A ColumnMetadataBuilder.
ColumnMetadataBuilder& IsReadOnly(bool is_read_only);

/// \brief Set the IsSearchable in the KeyValueMetadata object.
/// \param[in] IsSearchable The IsSearchable.
/// \return A ColumnMetadataBuilder.
ColumnMetadataBuilder& IsSearchable(bool is_searchable);

ColumnMetadata Build() const;
};
};
} // namespace sql
} // namespace flight
} // namespace arrow
21 changes: 21 additions & 0 deletions cpp/src/arrow/flight/sql/example/sqlite_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,27 @@ std::shared_ptr<DataType> GetArrowType(const char* sqlite_type) {
}
}

int32_t GetSqlTypeFromTypeName(const char* sqlite_type) {
if (sqlite_type == NULLPTR) {
// SQLite may not know the column type yet.
return SQLITE_NULL;
}

if (boost::iequals(sqlite_type, "int") || boost::iequals(sqlite_type, "integer")) {
return SQLITE_INTEGER;
} else if (boost::iequals(sqlite_type, "REAL")) {
return SQLITE_FLOAT;
} else if (boost::iequals(sqlite_type, "BLOB")) {
return SQLITE_BLOB;
} else if (boost::iequals(sqlite_type, "TEXT") ||
boost::istarts_with(sqlite_type, "char") ||
boost::istarts_with(sqlite_type, "varchar")) {
return SQLITE_TEXT;
} else {
return SQLITE_NULL;
}
}

class SQLiteFlightSqlServer::Impl {
sqlite3* db_;
std::map<std::string, std::shared_ptr<SqliteStatement>> prepared_statements_;
Expand Down
Loading