| 1337 | } |
| 1338 | |
| 1339 | SQLRETURN SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT record_number, |
| 1340 | SQLUSMALLINT field_identifier, |
| 1341 | SQLPOINTER character_attribute_ptr, SQLSMALLINT buffer_length, |
| 1342 | SQLSMALLINT* output_length, SQLLEN* numeric_attribute_ptr) { |
| 1343 | ARROW_LOG(DEBUG) << "SQLColAttributeW called with stmt: " << stmt |
| 1344 | << ", record_number: " << record_number |
| 1345 | << ", field_identifier: " << field_identifier |
| 1346 | << ", character_attribute_ptr: " << character_attribute_ptr |
| 1347 | << ", buffer_length: " << buffer_length |
| 1348 | << ", output_length: " << static_cast<const void*>(output_length) |
| 1349 | << ", numeric_attribute_ptr: " |
| 1350 | << static_cast<const void*>(numeric_attribute_ptr); |
| 1351 | |
| 1352 | using ODBC::ODBCDescriptor; |
| 1353 | using ODBC::ODBCStatement; |
| 1354 | return ODBCStatement::ExecuteWithDiagnostics(stmt, SQL_ERROR, [=]() { |
| 1355 | ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(stmt); |
| 1356 | ODBCDescriptor* ird = statement->GetIRD(); |
| 1357 | SQLINTEGER output_length_int; |
| 1358 | switch (field_identifier) { |
| 1359 | // Numeric attributes |
| 1360 | // internal is SQLLEN, no conversion is needed |
| 1361 | case SQL_DESC_DISPLAY_SIZE: |
| 1362 | case SQL_DESC_OCTET_LENGTH: { |
| 1363 | ird->GetField(record_number, field_identifier, numeric_attribute_ptr, |
| 1364 | buffer_length, &output_length_int); |
| 1365 | break; |
| 1366 | } |
| 1367 | // internal is SQLULEN, conversion is needed. |
| 1368 | case SQL_COLUMN_LENGTH: // ODBC 2.0 |
| 1369 | case SQL_DESC_LENGTH: { |
| 1370 | SQLULEN temp; |
| 1371 | ird->GetField(record_number, field_identifier, &temp, buffer_length, |
| 1372 | &output_length_int); |
| 1373 | if (numeric_attribute_ptr) { |
| 1374 | *numeric_attribute_ptr = static_cast<SQLLEN>(temp); |
| 1375 | } |
| 1376 | break; |
| 1377 | } |
| 1378 | // internal is SQLINTEGER, conversion is needed. |
| 1379 | case SQL_DESC_AUTO_UNIQUE_VALUE: |
| 1380 | case SQL_DESC_CASE_SENSITIVE: |
| 1381 | case SQL_DESC_NUM_PREC_RADIX: { |
| 1382 | SQLINTEGER temp; |
| 1383 | ird->GetField(record_number, field_identifier, &temp, buffer_length, |
| 1384 | &output_length_int); |
| 1385 | if (numeric_attribute_ptr) { |
| 1386 | *numeric_attribute_ptr = static_cast<SQLLEN>(temp); |
| 1387 | } |
| 1388 | break; |
| 1389 | } |
| 1390 | // internal is SQLSMALLINT, conversion is needed. |
| 1391 | case SQL_DESC_CONCISE_TYPE: |
| 1392 | case SQL_DESC_COUNT: |
| 1393 | case SQL_DESC_FIXED_PREC_SCALE: |
| 1394 | case SQL_DESC_TYPE: |
| 1395 | case SQL_DESC_NULLABLE: |
| 1396 | case SQL_COLUMN_PRECISION: // ODBC 2.0 |