Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
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
10 changes: 10 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/entry_points.cc
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,13 @@ SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attribute, SQLPOINTER
SQLINTEGER stringLength) {
return arrow::SQLSetStmtAttr(stmt, attribute, valuePtr, stringLength);
}

SQLRETURN SQL_API SQLDescribeCol(SQLHSTMT statementHandle, SQLUSMALLINT columnNumber,
SQLWCHAR* columnName, SQLSMALLINT bufferLength,
SQLSMALLINT* nameLengthPtr, SQLSMALLINT* dataTypePtr,
SQLULEN* columnSizePtr, SQLSMALLINT* decimalDigitsPtr,
SQLSMALLINT* nullablePtr) {
return arrow::SQLDescribeCol(statementHandle, columnNumber, columnName, bufferLength,
nameLengthPtr, dataTypePtr, columnSizePtr,
decimalDigitsPtr, nullablePtr);
}
1 change: 1 addition & 0 deletions cpp/src/arrow/flight/sql/odbc/odbc.def
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ EXPORTS
SQLColAttributeW
SQLColumnsW
SQLConnectW
SQLDescribeColW
SQLDisconnect
SQLDriverConnectW
SQLExecDirectW
Expand Down
114 changes: 114 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/odbc_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1367,4 +1367,118 @@ SQLRETURN SQLNativeSql(SQLHDBC connectionHandle, SQLWCHAR* inStatementText,
});
}

SQLRETURN SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT columnNumber, SQLWCHAR* columnName,
SQLSMALLINT bufferLength, SQLSMALLINT* nameLengthPtr,
SQLSMALLINT* dataTypePtr, SQLULEN* columnSizePtr,
SQLSMALLINT* decimalDigitsPtr, SQLSMALLINT* nullablePtr) {
LOG_DEBUG(
"SQLDescribeColW called with stmt: {}, columnNumber: {}, "
"columnName: {}, bufferLength: {}, nameLengthPtr: {}, dataTypePtr: {}, "
"columnSizePtr: {}, decimalDigitsPtr: {}, nullablePtr: {}",
stmt, columnNumber, fmt::ptr(columnName), bufferLength, fmt::ptr(nameLengthPtr),
fmt::ptr(dataTypePtr), fmt::ptr(columnSizePtr), fmt::ptr(decimalDigitsPtr),
fmt::ptr(nullablePtr));
using ODBC::ODBCDescriptor;
using ODBC::ODBCStatement;

return ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() {
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(stmt);
ODBCDescriptor* ird = statement->GetIRD();
SQLINTEGER outputLengthInt;
SQLSMALLINT sqlType;

// Column SQL Type
ird->GetField(columnNumber, SQL_DESC_CONCISE_TYPE, &sqlType, sizeof(SQLSMALLINT),
nullptr);
if (dataTypePtr) {
*dataTypePtr = sqlType;
}

// Column Name
if (columnName || nameLengthPtr) {
ird->GetField(columnNumber, SQL_DESC_NAME, columnName, bufferLength,
&outputLengthInt);
if (nameLengthPtr) {
*nameLengthPtr = static_cast<SQLSMALLINT>(outputLengthInt);
}
}

// Column Size
if (columnSizePtr) {
switch (sqlType) {
// All numeric types
case SQL_DECIMAL:
case SQL_NUMERIC:
case SQL_TINYINT:
case SQL_SMALLINT:
case SQL_INTEGER:
case SQL_BIGINT:
case SQL_REAL:
case SQL_FLOAT:
case SQL_DOUBLE: {
ird->GetField(columnNumber, SQL_DESC_PRECISION, columnSizePtr, sizeof(SQLULEN),
nullptr);
break;
}

default: {
ird->GetField(columnNumber, SQL_DESC_LENGTH, columnSizePtr, sizeof(SQLULEN),
nullptr);
}
}
}

// Column Decimal Digits
if (decimalDigitsPtr) {
switch (sqlType) {
// All exact numeric types
case SQL_TINYINT:
case SQL_SMALLINT:
case SQL_INTEGER:
case SQL_BIGINT:
case SQL_DECIMAL:
case SQL_NUMERIC: {
ird->GetField(columnNumber, SQL_DESC_SCALE, decimalDigitsPtr, sizeof(SQLULEN),
nullptr);
break;
}

// All datetime types (ODBC2)
case SQL_DATE:
case SQL_TIME:
case SQL_TIMESTAMP:
// All datetime types (ODBC3)
case SQL_TYPE_DATE:
case SQL_TYPE_TIME:
case SQL_TYPE_TIMESTAMP:
// All interval types with a seconds component
case SQL_INTERVAL_SECOND:
case SQL_INTERVAL_MINUTE_TO_SECOND:
case SQL_INTERVAL_HOUR_TO_SECOND:
case SQL_INTERVAL_DAY_TO_SECOND: {
ird->GetField(columnNumber, SQL_DESC_PRECISION, decimalDigitsPtr,
sizeof(SQLULEN), nullptr);
break;
}

default: {
// All character and binary types
// SQL_BIT
// All approximate numeric types
// All interval types with no seconds component
*decimalDigitsPtr = static_cast<SQLSMALLINT>(0);
}
}
}

// Column Nullable
if (nullablePtr) {
ird->GetField(columnNumber, SQL_DESC_NULLABLE, nullablePtr, sizeof(SQLSMALLINT),
nullptr);
}

return SQL_SUCCESS;
});
}

} // namespace arrow
5 changes: 5 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/odbc_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,9 @@ SQLRETURN SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT dataType);
SQLRETURN SQLNativeSql(SQLHDBC connectionHandle, SQLWCHAR* inStatementText,
SQLINTEGER inStatementTextLength, SQLWCHAR* outStatementText,
SQLINTEGER bufferLength, SQLINTEGER* outStatementTextLength);
SQLRETURN SQLDescribeCol(SQLHSTMT statementHandle, SQLUSMALLINT columnNumber,
SQLWCHAR* columnName, SQLSMALLINT bufferLength,
SQLSMALLINT* nameLengthPtr, SQLSMALLINT* dataTypePtr,
SQLULEN* columnSizePtr, SQLSMALLINT* decimalDigitsPtr,
SQLSMALLINT* nullablePtr);
} // namespace arrow
Loading
Loading