Skip to content

SQL_BLOB (-98) column type code falsely classified as string_t in odbc_result::column_types(nanodbc::result const& r) #907

Open
@nattomi

Description

@nattomi

Th IBM Db2 driver sends the code -98 for BLOB column types. This should be captured by the BINARY block of the switch statement in odbc_result::column_types(nanodbc::result const& r), but unfortunately it falls through it and ends up captured by the default block:

    case SQL_BINARY:
    case SQL_VARBINARY:
    case SQL_LONGVARBINARY:
      types.push_back(raw_t);
      break;
    default:
      types.push_back(string_t);
      signal_unknown_field_type(type, r.column_name(i));
      break; 

The following patch solves the issue, but I don't want to submit it as a pull request because it also involves modifying nanodbc.

diff --git a/src/nanodbc/nanodbc.cpp b/src/nanodbc/nanodbc.cpp
index 846f038b..1e63bd40 100644
--- a/src/nanodbc/nanodbc.cpp
+++ b/src/nanodbc/nanodbc.cpp
@@ -93,6 +93,10 @@
 #ifndef SQL_SS_UDT
 #define SQL_SS_UDT (-151) // from sqlncli.h
 #endif
+// IBM Db2 specific SQL type for BLOB
+#ifndef SQL_BLOB
+#define SQL_BLOB (-98)
+#endif
 
 // Default to ODBC version defined by NANODBC_ODBC_VERSION if provided.
 #ifndef NANODBC_ODBC_VERSION
@@ -2977,6 +2981,7 @@ private:
             case SQL_VARBINARY:
             case SQL_LONGVARBINARY:
             case SQL_SS_UDT: // MSDN: Essentially, UDT is a varbinary type with additional metadata.
+           case SQL_BLOB:
                 col.ctype_ = SQL_C_BINARY;
                 col.blob_ = true;
                 col.clen_ = 0;
diff --git a/src/odbc_result.cpp b/src/odbc_result.cpp
index 14a8d2b5..7ee34a67 100644
--- a/src/odbc_result.cpp
+++ b/src/odbc_result.cpp
@@ -8,6 +8,10 @@
 #ifndef SQL_SS_TIME2
 #define SQL_SS_TIME2 (-154)
 #endif
+// IBM Db2 specific SQL type for BLOB
+#ifndef SQL_BLOB
+#define SQL_BLOB (-98)
+#endif
 namespace odbc {
 
 using odbc::utils::run_interruptible;
@@ -715,6 +719,7 @@ std::vector<r_type> odbc_result::column_types(nanodbc::result const& r) {
     case SQL_BINARY:
     case SQL_VARBINARY:
     case SQL_LONGVARBINARY:
+    case SQL_BLOB:
       types.push_back(raw_t);
       break;
     default:

The following R code can be used to generate a sample table with a 10MB BLOB column:

dbExecute(conn, "CREATE TABLE BLOB_TEST (ID INT, DATA BLOB(10485760))")

# Generate 10 MB of binary data (0xAA repeated)
raw_data <- as.raw(rep(0xAA, 10 * 1024 * 1024))

# Insert the data using parameterized query
dbExecute(conn, "INSERT INTO BLOB_TEST (ID, DATA) VALUES (?, ?)", 
          params = list(1L, list(raw_data)))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions