Skip to content

Commit a9f4a83

Browse files
committed
Extract SQLGetTypeInfo implementation
Co-Authored-By: alinalibq <[email protected]>
1 parent 42f27ab commit a9f4a83

File tree

5 files changed

+1745
-10
lines changed

5 files changed

+1745
-10
lines changed

cpp/src/arrow/flight/sql/odbc/odbc_api.cc

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -960,8 +960,60 @@ SQLRETURN SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT data_type) {
960960
// appropriate data types in `SEARCHABLE` field
961961
ARROW_LOG(DEBUG) << "SQLGetTypeInfoW called with stmt: " << stmt
962962
<< " data_type: " << data_type;
963-
// GH-47722 TODO: Implement SQLGetTypeInfo
964-
return SQL_INVALID_HANDLE;
963+
964+
using ODBC::ODBCStatement;
965+
return ODBC::ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() {
966+
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(stmt);
967+
968+
switch (data_type) {
969+
case SQL_ALL_TYPES:
970+
case SQL_CHAR:
971+
case SQL_VARCHAR:
972+
case SQL_LONGVARCHAR:
973+
case SQL_WCHAR:
974+
case SQL_WVARCHAR:
975+
case SQL_WLONGVARCHAR:
976+
case SQL_BIT:
977+
case SQL_BINARY:
978+
case SQL_VARBINARY:
979+
case SQL_LONGVARBINARY:
980+
case SQL_TINYINT:
981+
case SQL_SMALLINT:
982+
case SQL_INTEGER:
983+
case SQL_BIGINT:
984+
case SQL_NUMERIC:
985+
case SQL_DECIMAL:
986+
case SQL_FLOAT:
987+
case SQL_REAL:
988+
case SQL_DOUBLE:
989+
case SQL_GUID:
990+
case SQL_DATE:
991+
case SQL_TYPE_DATE:
992+
case SQL_TIME:
993+
case SQL_TYPE_TIME:
994+
case SQL_TIMESTAMP:
995+
case SQL_TYPE_TIMESTAMP:
996+
case SQL_INTERVAL_DAY:
997+
case SQL_INTERVAL_DAY_TO_HOUR:
998+
case SQL_INTERVAL_DAY_TO_MINUTE:
999+
case SQL_INTERVAL_DAY_TO_SECOND:
1000+
case SQL_INTERVAL_HOUR:
1001+
case SQL_INTERVAL_HOUR_TO_MINUTE:
1002+
case SQL_INTERVAL_HOUR_TO_SECOND:
1003+
case SQL_INTERVAL_MINUTE:
1004+
case SQL_INTERVAL_MINUTE_TO_SECOND:
1005+
case SQL_INTERVAL_SECOND:
1006+
case SQL_INTERVAL_YEAR:
1007+
case SQL_INTERVAL_YEAR_TO_MONTH:
1008+
case SQL_INTERVAL_MONTH:
1009+
statement->GetTypeInfo(data_type);
1010+
break;
1011+
default:
1012+
throw DriverException("Invalid SQL data type", "HY004");
1013+
}
1014+
1015+
return SQL_SUCCESS;
1016+
});
9651017
}
9661018

9671019
SQLRETURN SQLNativeSql(SQLHDBC conn, SQLWCHAR* in_statement_text,

cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_type_info.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,24 +108,26 @@ Result<std::shared_ptr<RecordBatch>> TransformInner(
108108
data.literal_suffix = reader.GetLiteralSuffix();
109109

110110
const auto& create_params = reader.GetCreateParams();
111-
if (create_params) {
111+
if (create_params && !create_params->empty()) {
112112
data.create_params = boost::algorithm::join(*create_params, ",");
113113
} else {
114114
data.create_params = nullopt;
115115
}
116116

117117
data.nullable = reader.GetNullable() ? NULLABILITY_NULLABLE : NULLABILITY_NO_NULLS;
118118
data.case_sensitive = reader.GetCaseSensitive();
119+
// GH-47237 return SEARCHABILITY_LIKE_ONLY and SEARCHABILITY_ALL_EXPECT_LIKE for
120+
// appropriate data types
119121
data.searchable = reader.GetSearchable() ? SEARCHABILITY_ALL : SEARCHABILITY_NONE;
120122
data.unsigned_attribute = reader.GetUnsignedAttribute();
121123
data.fixed_prec_scale = reader.GetFixedPrecScale();
122124
data.auto_unique_value = reader.GetAutoIncrement();
123125
data.local_type_name = reader.GetLocalTypeName();
124126
data.minimum_scale = reader.GetMinimumScale();
125127
data.maximum_scale = reader.GetMaximumScale();
126-
data.sql_data_type =
128+
data.sql_data_type = util::GetNonConciseDataType(
127129
EnsureRightSqlCharType(static_cast<SqlDataType>(reader.GetSqlDataType()),
128-
metadata_settings_.use_wide_char);
130+
metadata_settings_.use_wide_char));
129131
data.sql_datetime_sub =
130132
util::GetSqlDateTimeSubCode(static_cast<SqlDataType>(data.data_type));
131133
data.num_prec_radix = reader.GetNumPrecRadix();

cpp/src/arrow/flight/sql/odbc/odbc_impl/util.cc

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ SqlDataType GetDefaultSqlCharType(bool use_wide_char) {
5656
SqlDataType GetDefaultSqlVarcharType(bool use_wide_char) {
5757
return use_wide_char ? SqlDataType_WVARCHAR : SqlDataType_VARCHAR;
5858
}
59+
SqlDataType GetDefaultSqlLongVarcharType(bool use_wide_char) {
60+
return use_wide_char ? SqlDataType_WLONGVARCHAR : SqlDataType_LONGVARCHAR;
61+
}
5962
CDataType GetDefaultCCharType(bool use_wide_char) {
6063
return use_wide_char ? CDataType_WCHAR : CDataType_CHAR;
6164
}
@@ -146,6 +149,9 @@ SqlDataType EnsureRightSqlCharType(SqlDataType data_type, bool use_wide_char) {
146149
case SqlDataType_VARCHAR:
147150
case SqlDataType_WVARCHAR:
148151
return GetDefaultSqlVarcharType(use_wide_char);
152+
case SqlDataType_LONGVARCHAR:
153+
case SqlDataType_WLONGVARCHAR:
154+
return GetDefaultSqlLongVarcharType(use_wide_char);
149155
default:
150156
return data_type;
151157
}
@@ -747,10 +753,12 @@ bool NeedArrayConversion(Type::type original_type_id, CDataType data_type) {
747753
return data_type != CDataType_BINARY;
748754
case Type::DECIMAL128:
749755
return data_type != CDataType_NUMERIC;
756+
case Type::DURATION:
750757
case Type::LIST:
751758
case Type::LARGE_LIST:
752759
case Type::FIXED_SIZE_LIST:
753760
case Type::MAP:
761+
case Type::STRING_VIEW:
754762
case Type::STRUCT:
755763
return data_type == CDataType_CHAR || data_type == CDataType_WCHAR;
756764
default:
@@ -926,9 +934,9 @@ ArrayConvertTask GetConverter(Type::type original_type_id, CDataType target_type
926934

927935
auto seconds_from_epoch = GetTodayTimeFromEpoch();
928936

929-
auto third_converted_array = CheckConversion(
930-
arrow::compute::Add(second_converted_array,
931-
std::make_shared<Int64Scalar>(seconds_from_epoch * 1000)));
937+
auto third_converted_array = CheckConversion(arrow::compute::Add(
938+
second_converted_array,
939+
std::make_shared<arrow::Int64Scalar>(seconds_from_epoch * 1000)));
932940

933941
arrow::compute::CastOptions cast_options_2;
934942
cast_options_2.to_type = arrow::timestamp(TimeUnit::MILLI);
@@ -947,7 +955,7 @@ ArrayConvertTask GetConverter(Type::type original_type_id, CDataType target_type
947955

948956
auto second_converted_array = CheckConversion(arrow::compute::Add(
949957
first_converted_array,
950-
std::make_shared<Int64Scalar>(seconds_from_epoch * 1000000000)));
958+
std::make_shared<arrow::Int64Scalar>(seconds_from_epoch * 1000000000)));
951959

952960
arrow::compute::CastOptions cast_options_2;
953961
cast_options_2.to_type = arrow::timestamp(TimeUnit::NANO);
@@ -971,7 +979,7 @@ ArrayConvertTask GetConverter(Type::type original_type_id, CDataType target_type
971979
} else if (original_type_id == Type::DECIMAL128 &&
972980
(target_type == CDataType_CHAR || target_type == CDataType_WCHAR)) {
973981
return [=](const std::shared_ptr<Array>& original_array) {
974-
StringBuilder builder;
982+
arrow::StringBuilder builder;
975983
int64_t length = original_array->length();
976984
ThrowIfNotOK(builder.ReserveData(length));
977985

cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ add_arrow_test(flight_sql_odbc_test
3535
odbc_test_suite.cc
3636
odbc_test_suite.h
3737
connection_test.cc
38+
type_info_test.cc
3839
# Enable Protobuf cleanup after test execution
3940
# GH-46889: move protobuf_test_util to a more common location
4041
../../../../engine/substrait/protobuf_test_util.cc

0 commit comments

Comments
 (0)