Skip to content

Commit e7d8794

Browse files
authored
Implement SQLDescribeCol
1 parent 1012ee0 commit e7d8794

File tree

6 files changed

+789
-6
lines changed

6 files changed

+789
-6
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,13 @@ SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attribute, SQLPOINTER
287287
SQLINTEGER stringLength) {
288288
return arrow::SQLSetStmtAttr(stmt, attribute, valuePtr, stringLength);
289289
}
290+
291+
SQLRETURN SQL_API SQLDescribeCol(SQLHSTMT statementHandle, SQLUSMALLINT columnNumber,
292+
SQLWCHAR* columnName, SQLSMALLINT bufferLength,
293+
SQLSMALLINT* nameLengthPtr, SQLSMALLINT* dataTypePtr,
294+
SQLULEN* columnSizePtr, SQLSMALLINT* decimalDigitsPtr,
295+
SQLSMALLINT* nullablePtr) {
296+
return arrow::SQLDescribeCol(statementHandle, columnNumber, columnName, bufferLength,
297+
nameLengthPtr, dataTypePtr, columnSizePtr,
298+
decimalDigitsPtr, nullablePtr);
299+
}

cpp/src/arrow/flight/sql/odbc/odbc.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ EXPORTS
2828
SQLColAttributeW
2929
SQLColumnsW
3030
SQLConnectW
31+
SQLDescribeColW
3132
SQLDisconnect
3233
SQLDriverConnectW
3334
SQLExecDirectW

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

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,4 +1367,118 @@ SQLRETURN SQLNativeSql(SQLHDBC connectionHandle, SQLWCHAR* inStatementText,
13671367
});
13681368
}
13691369

1370+
SQLRETURN SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT columnNumber, SQLWCHAR* columnName,
1371+
SQLSMALLINT bufferLength, SQLSMALLINT* nameLengthPtr,
1372+
SQLSMALLINT* dataTypePtr, SQLULEN* columnSizePtr,
1373+
SQLSMALLINT* decimalDigitsPtr, SQLSMALLINT* nullablePtr) {
1374+
LOG_DEBUG(
1375+
"SQLDescribeColW called with stmt: {}, columnNumber: {}, "
1376+
"columnName: {}, bufferLength: {}, nameLengthPtr: {}, dataTypePtr: {}, "
1377+
"columnSizePtr: {}, decimalDigitsPtr: {}, nullablePtr: {}",
1378+
stmt, columnNumber, fmt::ptr(columnName), bufferLength, fmt::ptr(nameLengthPtr),
1379+
fmt::ptr(dataTypePtr), fmt::ptr(columnSizePtr), fmt::ptr(decimalDigitsPtr),
1380+
fmt::ptr(nullablePtr));
1381+
using ODBC::ODBCDescriptor;
1382+
using ODBC::ODBCStatement;
1383+
1384+
return ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() {
1385+
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(stmt);
1386+
ODBCDescriptor* ird = statement->GetIRD();
1387+
SQLINTEGER outputLengthInt;
1388+
SQLSMALLINT sqlType;
1389+
1390+
// Column SQL Type
1391+
ird->GetField(columnNumber, SQL_DESC_CONCISE_TYPE, &sqlType, sizeof(SQLSMALLINT),
1392+
nullptr);
1393+
if (dataTypePtr) {
1394+
*dataTypePtr = sqlType;
1395+
}
1396+
1397+
// Column Name
1398+
if (columnName || nameLengthPtr) {
1399+
ird->GetField(columnNumber, SQL_DESC_NAME, columnName, bufferLength,
1400+
&outputLengthInt);
1401+
if (nameLengthPtr) {
1402+
*nameLengthPtr = static_cast<SQLSMALLINT>(outputLengthInt);
1403+
}
1404+
}
1405+
1406+
// Column Size
1407+
if (columnSizePtr) {
1408+
switch (sqlType) {
1409+
// All numeric types
1410+
case SQL_DECIMAL:
1411+
case SQL_NUMERIC:
1412+
case SQL_TINYINT:
1413+
case SQL_SMALLINT:
1414+
case SQL_INTEGER:
1415+
case SQL_BIGINT:
1416+
case SQL_REAL:
1417+
case SQL_FLOAT:
1418+
case SQL_DOUBLE: {
1419+
ird->GetField(columnNumber, SQL_DESC_PRECISION, columnSizePtr, sizeof(SQLULEN),
1420+
nullptr);
1421+
break;
1422+
}
1423+
1424+
default: {
1425+
ird->GetField(columnNumber, SQL_DESC_LENGTH, columnSizePtr, sizeof(SQLULEN),
1426+
nullptr);
1427+
}
1428+
}
1429+
}
1430+
1431+
// Column Decimal Digits
1432+
if (decimalDigitsPtr) {
1433+
switch (sqlType) {
1434+
// All exact numeric types
1435+
case SQL_TINYINT:
1436+
case SQL_SMALLINT:
1437+
case SQL_INTEGER:
1438+
case SQL_BIGINT:
1439+
case SQL_DECIMAL:
1440+
case SQL_NUMERIC: {
1441+
ird->GetField(columnNumber, SQL_DESC_SCALE, decimalDigitsPtr, sizeof(SQLULEN),
1442+
nullptr);
1443+
break;
1444+
}
1445+
1446+
// All datetime types (ODBC2)
1447+
case SQL_DATE:
1448+
case SQL_TIME:
1449+
case SQL_TIMESTAMP:
1450+
// All datetime types (ODBC3)
1451+
case SQL_TYPE_DATE:
1452+
case SQL_TYPE_TIME:
1453+
case SQL_TYPE_TIMESTAMP:
1454+
// All interval types with a seconds component
1455+
case SQL_INTERVAL_SECOND:
1456+
case SQL_INTERVAL_MINUTE_TO_SECOND:
1457+
case SQL_INTERVAL_HOUR_TO_SECOND:
1458+
case SQL_INTERVAL_DAY_TO_SECOND: {
1459+
ird->GetField(columnNumber, SQL_DESC_PRECISION, decimalDigitsPtr,
1460+
sizeof(SQLULEN), nullptr);
1461+
break;
1462+
}
1463+
1464+
default: {
1465+
// All character and binary types
1466+
// SQL_BIT
1467+
// All approximate numeric types
1468+
// All interval types with no seconds component
1469+
*decimalDigitsPtr = static_cast<SQLSMALLINT>(0);
1470+
}
1471+
}
1472+
}
1473+
1474+
// Column Nullable
1475+
if (nullablePtr) {
1476+
ird->GetField(columnNumber, SQL_DESC_NULLABLE, nullablePtr, sizeof(SQLSMALLINT),
1477+
nullptr);
1478+
}
1479+
1480+
return SQL_SUCCESS;
1481+
});
1482+
}
1483+
13701484
} // namespace arrow

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,9 @@ SQLRETURN SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT dataType);
9696
SQLRETURN SQLNativeSql(SQLHDBC connectionHandle, SQLWCHAR* inStatementText,
9797
SQLINTEGER inStatementTextLength, SQLWCHAR* outStatementText,
9898
SQLINTEGER bufferLength, SQLINTEGER* outStatementTextLength);
99+
SQLRETURN SQLDescribeCol(SQLHSTMT statementHandle, SQLUSMALLINT columnNumber,
100+
SQLWCHAR* columnName, SQLSMALLINT bufferLength,
101+
SQLSMALLINT* nameLengthPtr, SQLSMALLINT* dataTypePtr,
102+
SQLULEN* columnSizePtr, SQLSMALLINT* decimalDigitsPtr,
103+
SQLSMALLINT* nullablePtr);
99104
} // namespace arrow

0 commit comments

Comments
 (0)