Uploaded image for project: 'MariaDB Connector/ODBC'
  1. MariaDB Connector/ODBC
  2. ODBC-126

Core dump when procedure returns more than 1 result set

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed (View Workflow)
    • Priority: Critical
    • Resolution: Fixed
    • Affects Version/s: 3.0.2
    • Fix Version/s: 3.0.4, 2.0.17
    • Component/s: General
    • Labels:
      None
    • Environment:
      Linux Centos 7.4.1708

      Description

      When a procedure returns more than 1 result set, fetching from the second result fails in SQLGetData().
      The following SQL is used to set up the test:

      CREATE OR REPLACE TABLE odbcbug(col1 INT, col2 INT);
      INSERT INTO odbcbug VALUES(1,2),(3,4),(5,6);
      delimiter //
      CREATE OR REPLACE PROCEDURE odbcbugp1()
      BEGIN
        SELECT col1, col2 FROM odbcbug;
        SELECT col1 FROM odbcbug;
      END;
      //
      CREATE OR REPLACE PROCEDURE odbcbugp2()
      BEGIN
        SELECT col1 FROM odbcbug;
        SELECT col1, col2 FROM odbcbug;
      END;
      //
      

      And the following cod is used for testing:

      #include <stdio.h>
      #include <string.h>
      #include <sqlext.h>
       
      int main(int argc, char *argv[])
         {
         SQLHANDLE hEnv, hConn, hStmt;
         SQLRETURN nRet;
         SQLCHAR szConnStr[2048];
         SQLCHAR szErrMsg[256];
         SQLLEN nInd;
         SQLSMALLINT nCols;
         int i;
         SQLCHAR szSQLState[5];
         SQLINTEGER nNativeErr;
         SQLSMALLINT sLen;
         SQLCHAR szDriverVer[256];
         SQLCHAR *pSQL;
         SQLCHAR szBuf[1024];
       
         if(argc < 2)
            {
            fprintf(stderr, "Usage: %s <SQL>\n", argv[0]);
            return 1;
            }
         pSQL = argv[1];
         SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
         SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
         SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hConn);
       
         strcpy(szConnStr, "DSN=MariaDB;UID=root;");
         if((nRet = SQLDriverConnect(hConn, NULL, szConnStr, SQL_NTS, NULL, 0,
           &sLen, SQL_DRIVER_NOPROMPT)) != SQL_SUCCESS)
            {
            SQLError(hEnv, hConn, SQL_NULL_HSTMT, NULL, NULL, szErrMsg, sizeof(szErrMsg), NULL);
            fprintf(stderr, "Error in connecting to MariaDB:\n%s\n", szErrMsg);
       
            return 1;
            }
       
         SQLAllocHandle(SQL_HANDLE_STMT, hConn, &hStmt);
         if((nRet = SQLExecDirect(hStmt, pSQL, SQL_NTS)) != SQL_SUCCESS)
            {
            SQLError(hEnv, hConn, hStmt, NULL, NULL, szErrMsg, sizeof(szErrMsg), NULL);
            fprintf(stderr, "Error in connecting to MariaDB:\n%s\nin\n%s\n", szErrMsg, pSQL);
       
            return 1;
            }
       
         for(;;)
            {
            SQLNumResultCols(hStmt, &nCols);
            printf("Num cols: %d\n", nCols);
       
            while((nRet = SQLFetch(hStmt)) == SQL_SUCCESS)
               {
               for(i = 0; i < nCols; i++)
                  {
                  if((nRet = SQLGetData(hStmt, i + 1, SQL_C_CHAR, szBuf, sizeof(szBuf),
                    &nInd)) != SQL_SUCCESS)
                     {
                     SQLError(hEnv, hConn, hStmt, NULL, NULL, szErrMsg, sizeof(szErrMsg), NULL);
                     fprintf(stderr, "Error in SQLGetData:\n%s\n", szErrMsg);
       
                     return 1;
                     }
                  printf("Col: %d = /%s/\n", i + 1, nInd == SQL_NULL_DATA ? "null" : ((char *) szBuf));
                  }
               }
       
            if(nRet != SQL_NO_DATA)
               {
               SQLError(hEnv, hConn, hStmt, NULL, NULL, szErrMsg, sizeof(szErrMsg), NULL);
               fprintf(stderr, "Error in SQLFetch:\n%s\n", szErrMsg);
       
               return 1;
               }
       
            if((nRet = SQLMoreResults(hStmt)) != SQL_SUCCESS)
               {
               if(nRet == SQL_NO_DATA)
                  {
                  printf("No more results\n");
                  break;
                  }
               SQLError(hEnv, hConn, hStmt, szSQLState, &nNativeErr, szErrMsg, sizeof(szErrMsg),
                 &sLen)  ;
               fprintf(stderr, "Err: %d SQL State: %5.5s\n", nRet, szSQLState);
               fprintf(stderr, "Native Error: %d\n", nNativeErr);
               fprintf(stderr, "Error in SQLMoreResults:\n%s\n", szErrMsg);
       
               return 1;
               }
           }
         return 0;
         }
      

      With the above program compiled:

      $ ./odbcbug "call odbcbugp1"
      Num cols: 2
      Col: 1 = /1/
      Col: 2 = /2/
      Col: 1 = /3/
      Col: 2 = /4/
      Col: 1 = /5/
      Col: 2 = /6/
      Num cols: 1
      Col: 1 = /1/
      Col: 1 = /3/
      Col: 1 = /5/
      No more results
      $ ./odbcbug "call odbcbugp2"
      Num cols: 1
      Col: 1 = /1/
      Col: 1 = /3/
      Col: 1 = /5/
      Num cols: 2
      Col: 1 = /1/
      Segmentation fault (core dumped)
      

      Note that this only fails when using ODBC 3.0.2, when running with 2.0.15 is works as expected.

        Attachments

          Activity

            People

            • Assignee:
              Lawrin Lawrin Novitsky
              Reporter:
              karlsson Anders Karlsson
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: