Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-91778

String length calculation in SQLBindParameter appears incorrect

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 5.15.3, 6.0.0 Beta2
    • SQL Support
    • None
    • All

    Description

      Looking at the code in /src/plugins/sqldrivers/odbc/qsql_odbc.cpp the case for QMetaType::QString does not seem to match the documentation when using unicode strings.

      The code (less relevant bits removed) is:

      case QMetaType::QString:
        const qsizetype strSize = str.length() * sizeof(SQLTCHAR);
        if (*ind != SQL_NULL_DATA)
            *ind = str.length() * sizeof(SQLTCHAR);
        [...]
        r = SQLBindParameter(d->hStmt,
                             i + 1,
                             qParamType[bindValueType(i) & QSql::InOut],
                             SQL_C_TCHAR,
                             strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
                             0, // god knows... don't change this!
                             0,
                             ba.data(),
                             ba.size(),
                             ind);
      

      There's two things that don't look right to me.

      1. Looking at Microsoft documentation for SQLBindParameter, the sixth parameter (commented above with "god knows... don't change this!") is ColumnSize. I believe this should be "strSize", as is used elsewhere in the code, including a few lines below.
        It's been like that for at least 10 years, so perhaps there was a reason for it in the past, but I don't know why it would be like that now.
      2. The second thing is the fifth argument. As far as I understand, SQL_WVARCHAR maps to VARWCHAR, VARWCHAR maps to NVarChar, and the documentation for NVarChar is here (or at lest the best sources I could find).
        So according to the docs:

        n defines the string size in byte-pairs

        This makes me believe that strSize should be the size in byte-pairs, not bytes.

      I also think that maybe the last parameter should use SQL_LEN_DATA_AT_EXEC, as "ind" appears to be the size in bytes. Maybe this should also be used to determine ColumnSize?

      To be clear, I'm not a database expert, and my reading of the documentation may be incorrect. But this looks odd to me, so maybe someone with more odbc/SQL knowledge should take a look?

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              mabrand Mark Brand
              tlander Tim Lander
              Votes:
              1 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes