Skip to content

Commit b9480f8

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

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
@@ -1238,8 +1238,110 @@ SQLRETURN SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT column_number, SQLWCHAR* co
12381238
<< ", decimal_digits_ptr: "
12391239
<< static_cast<const void*>(decimal_digits_ptr)
12401240
<< ", nullable_ptr: " << static_cast<const void*>(nullable_ptr);
1241-
// GH-47724 TODO: Implement SQLDescribeCol
1242-
return SQL_INVALID_HANDLE;
1241+
1242+
using ODBC::ODBCDescriptor;
1243+
using ODBC::ODBCStatement;
1244+
1245+
return ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() {
1246+
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(stmt);
1247+
ODBCDescriptor* ird = statement->GetIRD();
1248+
SQLINTEGER output_length_int;
1249+
SQLSMALLINT sql_type;
1250+
1251+
// Column SQL Type
1252+
ird->GetField(column_number, SQL_DESC_CONCISE_TYPE, &sql_type, sizeof(SQLSMALLINT),
1253+
nullptr);
1254+
if (data_type_ptr) {
1255+
*data_type_ptr = sql_type;
1256+
}
1257+
1258+
// Column Name
1259+
if (column_name || name_length_ptr) {
1260+
ird->GetField(column_number, SQL_DESC_NAME, column_name, buffer_length,
1261+
&output_length_int);
1262+
if (name_length_ptr) {
1263+
// returned length should be in characters
1264+
*name_length_ptr =
1265+
static_cast<SQLSMALLINT>(output_length_int / GetSqlWCharSize());
1266+
}
1267+
}
1268+
1269+
// Column Size
1270+
if (column_size_ptr) {
1271+
switch (sql_type) {
1272+
// All numeric types
1273+
case SQL_DECIMAL:
1274+
case SQL_NUMERIC:
1275+
case SQL_TINYINT:
1276+
case SQL_SMALLINT:
1277+
case SQL_INTEGER:
1278+
case SQL_BIGINT:
1279+
case SQL_REAL:
1280+
case SQL_FLOAT:
1281+
case SQL_DOUBLE: {
1282+
ird->GetField(column_number, SQL_DESC_PRECISION, column_size_ptr,
1283+
sizeof(SQLULEN), nullptr);
1284+
break;
1285+
}
1286+
1287+
default: {
1288+
ird->GetField(column_number, SQL_DESC_LENGTH, column_size_ptr, sizeof(SQLULEN),
1289+
nullptr);
1290+
}
1291+
}
1292+
}
1293+
1294+
// Column Decimal Digits
1295+
if (decimal_digits_ptr) {
1296+
switch (sql_type) {
1297+
// All exact numeric types
1298+
case SQL_TINYINT:
1299+
case SQL_SMALLINT:
1300+
case SQL_INTEGER:
1301+
case SQL_BIGINT:
1302+
case SQL_DECIMAL:
1303+
case SQL_NUMERIC: {
1304+
ird->GetField(column_number, SQL_DESC_SCALE, decimal_digits_ptr,
1305+
sizeof(SQLULEN), nullptr);
1306+
break;
1307+
}
1308+
1309+
// All datetime types (ODBC 2)
1310+
case SQL_DATE:
1311+
case SQL_TIME:
1312+
case SQL_TIMESTAMP:
1313+
// All datetime types (ODBC 3)
1314+
case SQL_TYPE_DATE:
1315+
case SQL_TYPE_TIME:
1316+
case SQL_TYPE_TIMESTAMP:
1317+
// All interval types with a seconds component
1318+
case SQL_INTERVAL_SECOND:
1319+
case SQL_INTERVAL_MINUTE_TO_SECOND:
1320+
case SQL_INTERVAL_HOUR_TO_SECOND:
1321+
case SQL_INTERVAL_DAY_TO_SECOND: {
1322+
ird->GetField(column_number, SQL_DESC_PRECISION, decimal_digits_ptr,
1323+
sizeof(SQLULEN), nullptr);
1324+
break;
1325+
}
1326+
1327+
default: {
1328+
// All character and binary types
1329+
// SQL_BIT
1330+
// All approximate numeric types
1331+
// All interval types with no seconds component
1332+
*decimal_digits_ptr = static_cast<SQLSMALLINT>(0);
1333+
}
1334+
}
1335+
}
1336+
1337+
// Column Nullable
1338+
if (nullable_ptr) {
1339+
ird->GetField(column_number, SQL_DESC_NULLABLE, nullable_ptr, sizeof(SQLSMALLINT),
1340+
nullptr);
1341+
}
1342+
1343+
return SQL_SUCCESS;
1344+
});
12431345
}
12441346

12451347
} // 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,10 +34,13 @@ 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_attr_test.cc
3839
connection_test.cc
3940
statement_attr_test.cc
4041
statement_test.cc
42+
tables_test.cc
43+
type_info_test.cc
4144
# Enable Protobuf cleanup after test execution
4245
# GH-46889: move protobuf_test_util to a more common location
4346
../../../../engine/substrait/protobuf_test_util.cc

0 commit comments

Comments
 (0)