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

Single insertion cannot set default values

    XMLWordPrintable

Details

    • Bug
    • Status: Closed (View Workflow)
    • Critical
    • Resolution: Not a Bug
    • 3.4.7
    • N/A
    • API
    • win10;

    Description

      Is it true that explicit insertion without bulk cannot prompt the use of default values

      int main()
      {
       
          ::MYSQL *mysql = defalt_init_mysql();
       
          // 清理测试数据
          drop_table(mysql, "test_times");
       
          // 创建测试表,只包含枚举字段
          const char *create_sql = R"(
           CREATE TABLE test_times (
              id INT PRIMARY KEY AUTO_INCREMENT,
              created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
              updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
              last_login TIMESTAMP NULL
              )
          )";
          execute_sql(mysql, create_sql);
       
          // NOTE: bulk OK
          {
              // 准备插入语句
              const char *insert_sql = "INSERT INTO test_times (id,created_at, updated_at, "
                                       "last_login) VALUES (?,?, ?, ?)";
              MYSQL_STMT *stmt = mysql_stmt_init(mysql);
       
              if (mysql_stmt_prepare(stmt, insert_sql, strlen(insert_sql)))
              {
                  show_mysql_error(mysql, "准备语句失败");
                  return -1;
              }
       
              // 设置批量大小
              constexpr unsigned int array_size = 3;
              mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
       
              // 准备数据数组
              MYSQL_TIME created_at[array_size]{};   // created_at 时间戳
              MYSQL_TIME updated_at[array_size]{};   // updated_at 时间戳
              MYSQL_TIME last_login[array_size]{};   // last_login 时间戳
              my_bool created_at_null[array_size]{}; // created_at NULL 标记
              my_bool updated_at_null[array_size]{}; // updated_at NULL 标记
              my_bool last_login_null[array_size]{}; // last_login NULL 标记
       
              created_at[0].year = 2023;
              created_at[0].month = 5;
              created_at[0].day = 15;
              created_at[0].hour = 14;
              created_at[0].minute = 30;
              created_at[0].second = 45;
       
              created_at[1].year = 2023;
              created_at[1].month = 5;
              created_at[1].day = 16;
              created_at[1].hour = 15;
              created_at[1].minute = 31;
              created_at[1].second = 46;
       
              created_at[2].year = 2023;
              created_at[2].month = 5;
              created_at[2].day = 17;
              created_at[2].hour = 16;
              created_at[2].minute = 32;
              created_at[2].second = 47;
              created_at[2].second_part = 123456;
       
              updated_at[0].year = 2023;
              updated_at[0].month = 5;
              updated_at[0].day = 15;
              updated_at[0].hour = 14;
              updated_at[0].minute = 30;
              updated_at[0].second = 45;
       
              updated_at[1].year = 2023;
              updated_at[1].month = 5;
              updated_at[1].day = 16;
              updated_at[1].hour = 15;
              updated_at[1].minute = 31;
              updated_at[1].second = 46;
       
              updated_at[2].year = 2023;
              updated_at[2].month = 5;
              updated_at[2].day = 17;
              updated_at[2].hour = 16;
              updated_at[2].minute = 32;
              updated_at[2].second = 47;
              updated_at[2].second_part = 123456;
       
              std::vector<MYSQL_TIME *> created_at_ptr{&created_at[0], &created_at[1],
                                                       &created_at[2]};
              std::vector<MYSQL_TIME *> updated_at_ptr{&updated_at[0], &updated_at[1],
                                                       &updated_at[2]};
       
              // 绑定参数
              MYSQL_BIND bind[4]{};
              memset(bind, 0, sizeof(bind));
              char null_ind[] = {::STMT_INDICATOR_NULL, ::STMT_INDICATOR_NULL,
                                 ::STMT_INDICATOR_NULL};
              char default_ind[] = {::STMT_INDICATOR_DEFAULT, ::STMT_INDICATOR_DEFAULT,
                                    ::STMT_INDICATOR_DEFAULT};
              bind[0].buffer_type = MYSQL_TYPE_LONG;
              bind[0].u.indicator = null_ind;
       
              // created_at 参数
              // bind[1].buffer_type = MYSQL_TYPE_TIMESTAMP;
              bind[1].buffer_type = MYSQL_TYPE_STRING;
              // bind[1].buffer = created_at_ptr.data();
              // bind[1].u.indicator = null_ind; // NOTE: 会是null
              bind[1].u.indicator = default_ind; // NOTE: 会填默认值
       
              // updated_at 参数
              // bind[2].buffer_type = MYSQL_TYPE_TIMESTAMP;
              bind[2].buffer_type = MYSQL_TYPE_STRING;
              // bind[2].buffer = updated_at_ptr.data();
              // bind[2].u.indicator = null_ind; // NOTE: 会是null
              bind[2].u.indicator = default_ind; // NOTE: 会填默认值
       
              // last_login 参数
              bind[3].buffer_type = MYSQL_TYPE_TIMESTAMP;
              // bind[3].buffer = last_login;
              bind[3].u.indicator = null_ind;
       
              if (mysql_stmt_bind_param(stmt, bind))
              {
                  show_mysql_error(mysql, "绑定参数失败");
                  mysql_stmt_close(stmt);
                  return -1;
              }
       
              // 执行插入
              if (mysql_stmt_execute(stmt))
              {
                  show_mysql_error(mysql, "执行失败");
              }
              else
              {
                  std::cout << "插入成功!" << std::endl;
              }
              mysql_stmt_close(stmt);
          }
       
          // NOTE: has bug
          {
              const char *insert_sql = "INSERT INTO test_times (id,created_at, updated_at, "
                                       "last_login) VALUES (?,?,?,?)";
              MYSQL_STMT *stmt = mysql_stmt_init(mysql);
              char null_ind = STMT_INDICATOR_NULL;
              char default_ind = ::STMT_INDICATOR_DEFAULT;
       
              MYSQL_BIND bind[4]{};
              bind[0].buffer_type = MYSQL_TYPE_LONG;
              bind[0].u.indicator = &null_ind;
       
              bind[1].buffer_type = MYSQL_TYPE_TIMESTAMP;
              bind[1].u.indicator = &default_ind;
       
              bind[2].buffer_type = MYSQL_TYPE_STRING;
              bind[2].u.indicator = &default_ind;
       
              bind[3].buffer_type = MYSQL_TYPE_STRING;
              // NOTE: if TEST_BUG==0 ,It is NULL instead of DEFAULT in(created_at,updated_at)
      #define TEST_BUG 1
      #define TEST_CRASH 0
       
      #if TEST_BUG
       
          #if TEST_CRASH
              bind[3].is_null_value = 1;
          #else
              bind[3].u.indicator = &null_ind;
          #endif
       
      #else
              bind[3].is_null_value = 1;
      #endif
       
              if (mysql_stmt_prepare(stmt, insert_sql, strlen(insert_sql)))
              {
                  show_mysql_error(mysql, "准备语句失败");
                  return -1;
              }
       
      #if TEST_BUG
              // NOTE: requires all column'attr-indicator be set. other crash
              constexpr unsigned int array_size = 1;
              mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
      #endif
       
              if (mysql_stmt_bind_param(stmt, bind))
              {
                  show_mysql_error(mysql, "绑定参数失败");
                  mysql_stmt_close(stmt);
                  return -1;
              }
       
              // 执行插入
              if (mysql_stmt_execute(stmt))
              {
                  show_mysql_error(mysql, "执行失败");
              }
              else
              {
                  std::cout << "插入成功!" << std::endl;
              }
              mysql_stmt_close(stmt);
          }
          // NOTE: Single insertion cannot work with mix indicator
       
          ::mysql_close(mysql);
          std::cout << "main done\n";
          return 0;
      }
      

      Attachments

        Activity

          People

            georg Georg Richter
            9587 mcs
            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.