Skip to content

Commit 3651989

Browse files
alinaliBQrscales
andcommitted
Extract implementation of SQLDescribeCol
type_info_test.cc has duplicate changes as #48051 Co-Authored-By: rscales <[email protected]>
1 parent 42f27ab commit 3651989

File tree

5 files changed

+2732
-2
lines changed

5 files changed

+2732
-2
lines changed

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

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -994,8 +994,110 @@ SQLRETURN SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT column_number, SQLWCHAR* co
994994
<< ", decimal_digits_ptr: "
995995
<< static_cast<const void*>(decimal_digits_ptr)
996996
<< ", nullable_ptr: " << static_cast<const void*>(nullable_ptr);
997-
// GH-47724 TODO: Implement SQLDescribeCol
998-
return SQL_INVALID_HANDLE;
997+
998+
using ODBC::ODBCDescriptor;
999+
using ODBC::ODBCStatement;
1000+
1001+
return ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() {
1002+
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(stmt);
1003+
ODBCDescriptor* ird = statement->GetIRD();
1004+
SQLINTEGER output_length_int;
1005+
SQLSMALLINT sql_type;
1006+
1007+
// Column SQL Type
1008+
ird->GetField(column_number, SQL_DESC_CONCISE_TYPE, &sql_type, sizeof(SQLSMALLINT),
1009+
nullptr);
1010+
if (data_type_ptr) {
1011+
*data_type_ptr = sql_type;
1012+
}
1013+
1014+
// Column Name
1015+
if (column_name || name_length_ptr) {
1016+
ird->GetField(column_number, SQL_DESC_NAME, column_name, buffer_length,
1017+
&output_length_int);
1018+
if (name_length_ptr) {
1019+
// returned length should be in characters
1020+
*name_length_ptr =
1021+
static_cast<SQLSMALLINT>(output_length_int / GetSqlWCharSize());
1022+
}
1023+
}
1024+
1025+
// Column Size
1026+
if (column_size_ptr) {
1027+
switch (sql_type) {
1028+
// All numeric types
1029+
case SQL_DECIMAL:
1030+
case SQL_NUMERIC:
1031+
case SQL_TINYINT:
1032+
case SQL_SMALLINT:
1033+
case SQL_INTEGER:
1034+
case SQL_BIGINT:
1035+
case SQL_REAL:
1036+
case SQL_FLOAT:
1037+
case SQL_DOUBLE: {
1038+
ird->GetField(column_number, SQL_DESC_PRECISION, column_size_ptr,
1039+
sizeof(SQLULEN), nullptr);
1040+
break;
1041+
}
1042+
1043+
default: {
1044+
ird->GetField(column_number, SQL_DESC_LENGTH, column_size_ptr, sizeof(SQLULEN),
1045+
nullptr);
1046+
}
1047+
}
1048+
}
1049+
1050+
// Column Decimal Digits
1051+
if (decimal_digits_ptr) {
1052+
switch (sql_type) {
1053+
// All exact numeric types
1054+
case SQL_TINYINT:
1055+
case SQL_SMALLINT:
1056+
case SQL_INTEGER:
1057+
case SQL_BIGINT:
1058+
case SQL_DECIMAL:
1059+
case SQL_NUMERIC: {
1060+
ird->GetField(column_number, SQL_DESC_SCALE, decimal_digits_ptr,
1061+
sizeof(SQLULEN), nullptr);
1062+
break;
1063+
}
1064+
1065+
// All datetime types (ODBC2)
1066+
case SQL_DATE:
1067+
case SQL_TIME:
1068+
case SQL_TIMESTAMP:
1069+
// All datetime types (ODBC3)
1070+
case SQL_TYPE_DATE:
1071+
case SQL_TYPE_TIME:
1072+
case SQL_TYPE_TIMESTAMP:
1073+
// All interval types with a seconds component
1074+
case SQL_INTERVAL_SECOND:
1075+
case SQL_INTERVAL_MINUTE_TO_SECOND:
1076+
case SQL_INTERVAL_HOUR_TO_SECOND:
1077+
case SQL_INTERVAL_DAY_TO_SECOND: {
1078+
ird->GetField(column_number, SQL_DESC_PRECISION, decimal_digits_ptr,
1079+
sizeof(SQLULEN), nullptr);
1080+
break;
1081+
}
1082+
1083+
default: {
1084+
// All character and binary types
1085+
// SQL_BIT
1086+
// All approximate numeric types
1087+
// All interval types with no seconds component
1088+
*decimal_digits_ptr = static_cast<SQLSMALLINT>(0);
1089+
}
1090+
}
1091+
}
1092+
1093+
// Column Nullable
1094+
if (nullable_ptr) {
1095+
ird->GetField(column_number, SQL_DESC_NULLABLE, nullable_ptr, sizeof(SQLSMALLINT),
1096+
nullptr);
1097+
}
1098+
1099+
return SQL_SUCCESS;
1100+
});
9991101
}
10001102

10011103
} // namespace arrow::flight::sql::odbc

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ add_arrow_test(flight_sql_odbc_test
3434
SOURCES
3535
odbc_test_suite.cc
3636
odbc_test_suite.h
37+
columns_test.cc
3738
connection_test.cc
39+
tables_test.cc
40+
type_info_test.cc
3841
# Enable Protobuf cleanup after test execution
3942
# GH-46889: move protobuf_test_util to a more common location
4043
../../../../engine/substrait/protobuf_test_util.cc

0 commit comments

Comments
 (0)