Skip to content

Commit

Permalink
test case and bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-ext-simba-hx committed Nov 13, 2024
1 parent 0ec489c commit 8236377
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 25 deletions.
49 changes: 31 additions & 18 deletions cpp/lib/ClientBindUploader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@


#include <sstream>
#include <vector>

#include "ClientBindUploader.hpp"
#include "../logger/SFLogger.hpp"
Expand Down Expand Up @@ -83,6 +84,7 @@ void ClientBindUploader::executeUploading(const std::string &sql,
std::basic_iostream<char>& uploadStream,
size_t dataSize)
{
snowflake_prepare(m_stmt, sql.c_str(), 0);
SF_STATUS ret = _snowflake_execute_put_get_native(m_stmt, &uploadStream, dataSize, NULL);
if (ret != SF_STATUS_SUCCESS)
{
Expand Down Expand Up @@ -111,44 +113,55 @@ _snowflake_stage_bind_upload(SF_STMT* sfstmt)
char name_buf[SF_PARAM_NAME_BUF_LEN];
char* name = NULL;
char* value = NULL;
struct bind_info {
SF_BIND_INPUT* input;
void* val_ptr;
int step;
};
std::vector<bind_info> bindInfo;
for (unsigned int i = 0; i < sfstmt->params_len; i++)
{
cJSON* binding;
SF_BIND_INPUT* input = _snowflake_get_binding_by_index(sfstmt, i, &name,
name_buf, SF_PARAM_NAME_BUF_LEN);
if (input == NULL)
{
log_error("_snowflake_execute_ex: No parameter by this name %s", name);
continue;
return NULL;
}
type = snowflake_type_to_string(
c_type_to_snowflake(input->c_type, SF_DB_TYPE_TIMESTAMP_NTZ));
cJSON* val_array = snowflake_cJSON_CreateArray();
size_t step = _snowflake_get_binding_value_size(input);
void* val_ptr = input->value;
size_t val_len;
cJSON* single_val = NULL;
for (int64 j = 0; j < sfstmt->paramset_size; j++, val_ptr = (char*)val_ptr + step)
bindInfo.emplace_back();
bindInfo.back().input = input;
bindInfo.back().val_ptr = input->value;
bindInfo.back().step = _snowflake_get_binding_value_size(input);
}
for (int64 i = 0; i < sfstmt->paramset_size; i++)
{
for (unsigned int j = 0; j < sfstmt->params_len; j++)
{
if (SF_BIND_LEN_NULL == input->len_ind[j])
SF_BIND_INPUT* input = bindInfo[j].input;
void* val_ptr = bindInfo[j].val_ptr;
int val_len = input->len;
if (input->len_ind)
{
val_len = input->len_ind[i];
}

if (SF_BIND_LEN_NULL == val_len)
{
uploader.addNullValue();
}

if ((SF_C_TYPE_STRING == input->c_type) &&
(SF_BIND_LEN_NTS == input->len_ind[j]))
(SF_BIND_LEN_NTS == val_len))
{
val_len = strlen((char*)val_ptr);
}
else
{
val_len = (size_t)(input->len_ind[j]);
}

value = value_to_string(val_ptr, val_len, input->c_type);
uploader.addStringValue(value, input->type);
if (value) {
uploader.addStringValue(value, input->type);
SF_FREE(value);
}
bindInfo[j].val_ptr = (char*)bindInfo[j].val_ptr + bindInfo[j].step;
}
}
bindStage = uploader.getStagePath();
Expand All @@ -161,7 +174,7 @@ _snowflake_stage_bind_upload(SF_STMT* sfstmt)
if (!bindStage.empty())
{
char* bind_stage = (char*) SF_CALLOC(1, bindStage.size() + 1);
sf_strncpy(bind_stage, bindStage.size(), bindStage.c_str(), bindStage.size());
sf_strncpy(bind_stage, bindStage.size() + 1, bindStage.c_str(), bindStage.size());
return bind_stage;
}

Expand Down
17 changes: 10 additions & 7 deletions lib/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1959,26 +1959,29 @@ cJSON* STDCALL _snowflake_get_binding_json(SF_STMT* sfstmt)
cJSON* val_array = snowflake_cJSON_CreateArray();
size_t step = _snowflake_get_binding_value_size(input);
void* val_ptr = input->value;
size_t val_len;
int64 val_len;
cJSON* single_val = NULL;
for (int64 j = 0; j < sfstmt->paramset_size; j++, val_ptr = (char*)val_ptr + step)
{
if (SF_BIND_LEN_NULL == input->len_ind[j])
val_len = input->len;
if (input->len_ind)
{
val_len = input->len_ind[j];
}

if (SF_BIND_LEN_NULL == val_len)
{
single_val = snowflake_cJSON_CreateNull();
snowflake_cJSON_AddItemToArray(val_array, single_val);
continue;
}

if ((SF_C_TYPE_STRING == input->c_type) &&
(SF_BIND_LEN_NTS == input->len_ind[j]))
(SF_BIND_LEN_NTS == val_len))
{
val_len = strlen((char*)val_ptr);
}
else
{
val_len = (size_t)(input->len_ind[j]);
}

value = value_to_string(val_ptr, val_len, input->c_type);
single_val = snowflake_cJSON_CreateString(value);
snowflake_cJSON_AddItemToArray(val_array, single_val);
Expand Down
183 changes: 183 additions & 0 deletions tests/test_bind_params.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <string.h>
#include "utils/test_setup.h"
#include "memory.h"

#define INPUT_ARRAY_SIZE 3

Expand Down Expand Up @@ -111,10 +112,192 @@ void test_bind_parameters(void **unused) {
snowflake_term(sf);
}

void test_array_binding_core(unsigned int array_size) {
/* init */
SF_STATUS status;
int8* int8_array = NULL;
int8 int8_value = -12;
char int8_expected_result[] = "-12";
uint8* uint8_array = NULL;
uint8 uint8_value = 12;
char uint8_expected_result[] = "12";
int64* int64_array = NULL;
int64 int64_value = -12345;
char int64_expected_result[] = "-12345";
uint64* uint64_array = NULL;
uint64 uint64_value = 12345;
char uint64_expected_result[] = "12345";
float64* float_array = NULL;
float64 float_value = 1.23;
char float_expected_result[] = "1.23";
char* string_array = NULL;
char string_value[] = "str";
char string_expected_result[] = "str";
byte* binary_array = NULL;
byte binary_value[] = {0x12, 0x34, 0x56, 0x78};
char binary_expected_result[] = "12345678";
sf_bool* bool_array = NULL;
sf_bool bool_value = SF_BOOLEAN_TRUE;
char bool_expected_result[] = "1";
SF_BIND_INPUT int8_input;
SF_BIND_INPUT uint8_input;
SF_BIND_INPUT int64_input;
SF_BIND_INPUT uint64_input;
SF_BIND_INPUT float_input;
SF_BIND_INPUT string_input;
SF_BIND_INPUT binary_input;
SF_BIND_INPUT bool_input;

SF_BIND_INPUT input_array[8];
char* expected_results[8];
unsigned int i = 0, j = 0;

// initialize bindings with argument
int8_array = SF_CALLOC(array_size, sizeof(int8_value));
uint8_array = SF_CALLOC(array_size, sizeof(uint8_value));
int64_array = SF_CALLOC(array_size, sizeof(int64_value));
uint64_array = SF_CALLOC(array_size, sizeof(uint64_value));
float_array = SF_CALLOC(array_size, sizeof(float_value));
string_array = SF_CALLOC(array_size, sizeof(string_value));
binary_array = SF_CALLOC(array_size, sizeof(binary_value));
bool_array = SF_CALLOC(array_size, sizeof(bool_value));

for (i = 0; i < array_size; i++)
{
int8_array[i] = int8_value;
uint8_array[i] = uint8_value;
int64_array[i] = int64_value;
uint64_array[i] = uint64_value;
float_array[i] = float_value;
memcpy(string_array + sizeof(string_value) * i, string_value, sizeof(string_value));
memcpy(binary_array + sizeof(binary_value) * i, binary_value, sizeof(binary_value));
bool_array[i] = bool_value;
}

snowflake_bind_input_init(&int8_input);
snowflake_bind_input_init(&uint8_input);
snowflake_bind_input_init(&int64_input);
snowflake_bind_input_init(&uint64_input);
snowflake_bind_input_init(&float_input);
snowflake_bind_input_init(&string_input);
snowflake_bind_input_init(&binary_input);
snowflake_bind_input_init(&bool_input);

int8_input.idx = 1;
int8_input.c_type = SF_C_TYPE_INT8;
int8_input.value = int8_array;

uint8_input.idx = 2;
uint8_input.c_type = SF_C_TYPE_UINT8;
uint8_input.value = uint8_array;

int64_input.idx = 3;
int64_input.c_type = SF_C_TYPE_INT64;
int64_input.value = int64_array;

uint64_input.idx = 4;
uint64_input.c_type = SF_C_TYPE_UINT64;
uint64_input.value = uint64_array;

float_input.idx = 5;
float_input.c_type = SF_C_TYPE_FLOAT64;
float_input.value = float_array;

string_input.idx = 6;
string_input.c_type = SF_C_TYPE_STRING;
string_input.value = string_array;
string_input.len = sizeof(string_value);

binary_input.idx = 7;
binary_input.c_type = SF_C_TYPE_BINARY;
binary_input.value = binary_array;
binary_input.len = sizeof(binary_value);

bool_input.idx = 8;
bool_input.c_type = SF_C_TYPE_BOOLEAN;
bool_input.value = bool_array;

input_array[0] = int8_input;
input_array[1] = uint8_input;
input_array[2] = int64_input;
input_array[3] = uint64_input;
input_array[4] = float_input;
input_array[5] = string_input;
input_array[6] = binary_input;
input_array[7] = bool_input;

expected_results[0] = int8_expected_result;
expected_results[1] = uint8_expected_result;
expected_results[2] = int64_expected_result;
expected_results[3] = uint64_expected_result;
expected_results[4] = float_expected_result;
expected_results[5] = string_expected_result;
expected_results[6] = binary_expected_result;
expected_results[7] = bool_expected_result;

/* Connect with all parameters set */
SF_CONNECT* sf = setup_snowflake_connection();
status = snowflake_connect(sf);
assert_int_equal(status, SF_STATUS_SUCCESS);

/* Create a statement once and reused */
SF_STMT* stmt = snowflake_stmt(sf);
status = snowflake_query(
stmt,
"create or replace temporary table t (c1 number, c2 number, c3 number, c4 number, c5 float, c6 string, c7 binary, c8 boolean)",
0
);
assert_int_equal(status, SF_STATUS_SUCCESS);

int64 paramset_size = array_size;
status = snowflake_stmt_set_attr(stmt, SF_STMT_PARAMSET_SIZE, &paramset_size);
status = snowflake_prepare(
stmt,
"insert into t values(?, ?, ?, ?, ?, ?, ?, ?)",
0
);
assert_int_equal(status, SF_STATUS_SUCCESS);

status = snowflake_bind_param_array(stmt, input_array, sizeof(input_array) / sizeof(SF_BIND_INPUT));
assert_int_equal(status, SF_STATUS_SUCCESS);

status = snowflake_execute(stmt);
assert_int_equal(status, SF_STATUS_SUCCESS);
assert_int_equal(snowflake_affected_rows(stmt), array_size);

status = snowflake_query(stmt, "select * from t", 0);
assert_int_equal(status, SF_STATUS_SUCCESS);
assert_int_equal(snowflake_num_rows(stmt), array_size);

for (i = 0; i < array_size; i++)
{
status = snowflake_fetch(stmt);
assert_int_equal(status, SF_STATUS_SUCCESS);
char* result = NULL;
for (j = 0; j < 8; j++)
{
snowflake_column_as_const_str(stmt, j + 1, &result);
assert_string_equal(result, expected_results[j]);
}
}
snowflake_stmt_term(stmt);
snowflake_term(sf);
}

void test_array_binding_normal(void** unused) {
test_array_binding_core(1000);
}

void test_array_binding_stage(void** unused) {
test_array_binding_core(100000);
}

int main(void) {
initialize_test(SF_BOOLEAN_FALSE);
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_bind_parameters),
cmocka_unit_test(test_array_binding_normal),
cmocka_unit_test(test_array_binding_stage),
};
int ret = cmocka_run_group_tests(tests, NULL, NULL);
snowflake_global_term();
Expand Down

0 comments on commit 8236377

Please sign in to comment.