Uploaded image for project: 'MariaDB Connector/C'
  1. MariaDB Connector/C
  2. CONC-205

Any field going after a TEXT field in the selecion list, is fetched incorrectly

    XMLWordPrintable

Details

    • Bug
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Fixed
    • 2.3.1
    • 2.3.2
    • None
    • None

    Description

      Text column should be bound as MYSQL_TYPE_STRING
      The testcase:

      static int test_conc_new(MYSQL *mysql)
      {
        MYSQL_STMT *stmt;
        MYSQL_BIND my_bind[3];
        char       data[8];
        ulong      length[3];
        int        rc, int_col;
        short      smint_col;
        my_bool    is_null[3];
        char       *query = "SELECT text_col, smint_col, int_col FROM test_conc_new";
       
        rc= mysql_query(mysql, "drop table if exists test_conc_new");
        check_mysql_rc(rc, mysql);
        rc= mysql_query(mysql, "CREATE TABLE test_conc_new (text_col TEXT, smint_col SMALLINT, int_col INT)");
        check_mysql_rc(rc, mysql);
        rc= mysql_query(mysql, "INSERT INTO test_conc_new VALUES('data01', 21893, 1718038908), ('data2', -25734, -1857802040)");
        check_mysql_rc(rc, mysql);
       
        stmt= mysql_stmt_init(mysql);
        FAIL_IF(!stmt, mysql_error(mysql));
       
        rc= mysql_stmt_prepare(stmt, query, (unsigned long)strlen(query));
        check_stmt_rc(rc, stmt);
       
        memset(my_bind, '\0', sizeof(my_bind));
        my_bind[0].buffer_type= MYSQL_TYPE_STRING;
        my_bind[0].buffer= (void *)data;
        my_bind[0].buffer_length= sizeof(data);
        my_bind[0].is_null= &is_null[0];
        my_bind[0].length= &length[0];
       
        my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
        my_bind[1].buffer= &smint_col;
        my_bind[1].buffer_length= 2;
        my_bind[1].is_null= &is_null[1];
        my_bind[1].length= &length[1];
       
        my_bind[2].buffer_type= MYSQL_TYPE_LONG;
        my_bind[2].buffer= &int_col;
        my_bind[2].buffer_length= 4;
        my_bind[2].is_null= &is_null[2];
        my_bind[2].length= &length[2];
       
        rc= mysql_stmt_execute(stmt);
        check_stmt_rc(rc, stmt);
       
        rc= mysql_stmt_bind_result(stmt, my_bind);
        check_stmt_rc(rc, stmt);
       
        rc= mysql_stmt_fetch(stmt);
        check_stmt_rc(rc, stmt);
       
        FAIL_IF(length[0] != 6, "Wrong fetched string length");
        FAIL_IF(length[1] != 2, "Wrong fetched short length");
        FAIL_IF(length[2] != 4, "Wrong fetched int length");
       
        FAIL_IF(strncmp(data, "data01", length[0] + 1) != 0, "Wrong string value");
        FAIL_IF(smint_col != 21893, "Expected 21893");
        FAIL_IF(int_col != 1718038908, "Expected 1718038908");
       
        rc= mysql_stmt_fetch(stmt);
        check_stmt_rc(rc, stmt);
       
        FAIL_IF(length[0] != 5, "Wrong fetched string length");
        FAIL_IF(length[1] != 2, "Wrong fetched short length");
        FAIL_IF(length[2] != 4, "Wrong fetched int length");
       
        FAIL_IF(strncmp(data, "data2", length[0] + 1) != 0, "Wrong string value");
        FAIL_IF(smint_col != -25734, "Expected 21893");
        FAIL_IF(int_col != -1857802040, "Expected 1718038908");
       
        rc= mysql_stmt_fetch(stmt);
        FAIL_IF(rc != MYSQL_NO_DATA, "Expected MYSQL_NO_DATA");
       
        mysql_stmt_close(stmt);
       
        rc= mysql_query(mysql, "drop table test_conc_new");
        check_mysql_rc(rc, mysql);
       
        return OK;
      }
      

      The reason is that connector decrements field length before calculating next field value ptr. It does that because of terminating NULL it adds. But that NULL was not considered in the field length previously calculated. Following patch seems to fix the problem, and does not cause any testcase to fail.

      diff --git a/libmariadb/my_stmt_codec.c b/libmariadb/my_stmt_codec.c
      index fdaed55..a5d5b46 100644
      --- a/libmariadb/my_stmt_codec.c
      +++ b/libmariadb/my_stmt_codec.c
      @@ -935,10 +935,6 @@ void ps_fetch_bin(MYSQL_BIND *r_param, const MYSQL_FIELD *field,
           }
         }
         *r_param->error= copylen > r_param->buffer_length;
      -  /* don't count trailing zero if we fetch into string */
      -  if (r_param->buffer_type == MYSQL_TYPE_STRING &&
      -    !*r_param->error)
      -    field_length--;
         (*row)+= field_length;
       }
       /* }}} */
      

      Attachments

        1. conc205.diff
          4 kB
          Lawrin Novitsky
        2. my_stmt_codec.c
          32 kB
          Lawrin Novitsky
        3. ps_bugs.c
          136 kB
          Lawrin Novitsky

        Issue Links

          Activity

            People

              georg Georg Richter
              Lawrin Lawrin Novitsky
              Votes:
              0 Vote for this issue
              Watchers:
              1 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.