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

    • Bug
    • Status: Closed (View Workflow)
    • Critical
    • Resolution: Fixed
    • 3.0.2
    • 3.0.4, 2.0.17
    • General
    • None
    • 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

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

            Dates

              Created:
              Updated:
              Resolved:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.