| 1527 | } |
| 1528 | |
| 1529 | SQLRETURN SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT column_number, SQLWCHAR* column_name, |
| 1530 | SQLSMALLINT buffer_length, SQLSMALLINT* name_length_ptr, |
| 1531 | SQLSMALLINT* data_type_ptr, SQLULEN* column_size_ptr, |
| 1532 | SQLSMALLINT* decimal_digits_ptr, SQLSMALLINT* nullable_ptr) { |
| 1533 | ARROW_LOG(DEBUG) << "SQLDescribeColW called with stmt: " << stmt |
| 1534 | << ", column_number: " << column_number |
| 1535 | << ", column_name: " << static_cast<const void*>(column_name) |
| 1536 | << ", buffer_length: " << buffer_length |
| 1537 | << ", name_length_ptr: " << static_cast<const void*>(name_length_ptr) |
| 1538 | << ", data_type_ptr: " << static_cast<const void*>(data_type_ptr) |
| 1539 | << ", column_size_ptr: " << static_cast<const void*>(column_size_ptr) |
| 1540 | << ", decimal_digits_ptr: " |
| 1541 | << static_cast<const void*>(decimal_digits_ptr) |
| 1542 | << ", nullable_ptr: " << static_cast<const void*>(nullable_ptr); |
| 1543 | |
| 1544 | using ODBC::ODBCDescriptor; |
| 1545 | using ODBC::ODBCStatement; |
| 1546 | |
| 1547 | return ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() { |
| 1548 | ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(stmt); |
| 1549 | ODBCDescriptor* ird = statement->GetIRD(); |
| 1550 | SQLINTEGER output_length_int; |
| 1551 | SQLSMALLINT sql_type; |
| 1552 | |
| 1553 | // Column SQL Type |
| 1554 | ird->GetField(column_number, SQL_DESC_CONCISE_TYPE, &sql_type, sizeof(SQLSMALLINT), |
| 1555 | nullptr); |
| 1556 | if (data_type_ptr) { |
| 1557 | *data_type_ptr = sql_type; |
| 1558 | } |
| 1559 | |
| 1560 | // Column Name |
| 1561 | if (column_name || name_length_ptr) { |
| 1562 | ird->GetField(column_number, SQL_DESC_NAME, column_name, buffer_length, |
| 1563 | &output_length_int); |
| 1564 | if (name_length_ptr) { |
| 1565 | // returned length should be in characters |
| 1566 | *name_length_ptr = |
| 1567 | static_cast<SQLSMALLINT>(output_length_int / GetSqlWCharSize()); |
| 1568 | } |
| 1569 | } |
| 1570 | |
| 1571 | // Column Size |
| 1572 | if (column_size_ptr) { |
| 1573 | switch (sql_type) { |
| 1574 | // All numeric types |
| 1575 | case SQL_DECIMAL: |
| 1576 | case SQL_NUMERIC: |
| 1577 | case SQL_TINYINT: |
| 1578 | case SQL_SMALLINT: |
| 1579 | case SQL_INTEGER: |
| 1580 | case SQL_BIGINT: |
| 1581 | case SQL_REAL: |
| 1582 | case SQL_FLOAT: |
| 1583 | case SQL_DOUBLE: { |
| 1584 | ird->GetField(column_number, SQL_DESC_PRECISION, column_size_ptr, |
| 1585 | sizeof(SQLULEN), nullptr); |
| 1586 | break; |