ext/duckdb/prepared_statement.c in duckdb-1.1.2.0 vs ext/duckdb/prepared_statement.c in duckdb-1.1.2.1

- old
+ new

@@ -30,10 +30,11 @@ static VALUE duckdb_prepared_statement__bind_date(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day); static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE hour, VALUE min, VALUE sec, VALUE micros); static VALUE duckdb_prepared_statement__bind_timestamp(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros); static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VALUE months, VALUE days, VALUE micros); static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VALUE lower, VALUE upper); +static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale); static const rb_data_type_t prepared_statement_data_type = { "DuckDB/PreparedStatement", {NULL, deallocate, memsize,}, 0, 0, RUBY_TYPED_FREE_IMMEDIATELY @@ -69,11 +70,11 @@ obj = allocate(cDuckDBPreparedStatement); TypedData_Get_Struct(obj, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); if (duckdb_prepare_extracted_statement(con, extracted_statements, index, &(ctx->prepared_statement)) == DuckDBError) { - rb_raise(eDuckDBError, "Fail to get DuckDB::PreparedStatement object from ExtractedStatements object"); + rb_raise(eDuckDBError, "Failed to create DuckDB::PreparedStatement object."); } return obj; } static VALUE duckdb_prepared_statement_initialize(VALUE self, VALUE con, VALUE query) { @@ -102,15 +103,20 @@ static VALUE duckdb_prepared_statement_execute(VALUE self) { rubyDuckDBPreparedStatement *ctx; rubyDuckDBResult *ctxr; VALUE result = rbduckdb_create_result(); + const char *p = NULL; TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); ctxr = get_struct_result(result); if (duckdb_execute_prepared(ctx->prepared_statement, &(ctxr->result)) == DuckDBError) { - rb_raise(eDuckDBError, "%s", duckdb_result_error(&(ctxr->result))); + p = duckdb_result_error(&(ctxr->result)); + if (p == NULL) { + p = duckdb_prepare_error(ctx->prepared_statement); + } + rb_raise(eDuckDBError, "%s", p ? p : "Failed to execute prepared statement."); } return result; } /* @@ -397,10 +403,30 @@ } return self; } +static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale) { + duckdb_hugeint hugeint; + duckdb_decimal decimal; + rubyDuckDBPreparedStatement *ctx; + idx_t idx = check_index(vidx); + + TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); + hugeint.lower = NUM2ULL(lower); + hugeint.upper = NUM2LL(upper); + decimal.value = hugeint; + decimal.width = (uint8_t)NUM2UINT(width); + decimal.scale = (uint8_t)NUM2UINT(scale); + + if (duckdb_bind_decimal(ctx->prepared_statement, idx, decimal) == DuckDBError) { + rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx); + } + + return self; +} + rubyDuckDBPreparedStatement *get_struct_prepared_statement(VALUE self) { rubyDuckDBPreparedStatement *ctx; TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx); return ctx; } @@ -432,6 +458,7 @@ rb_define_private_method(cDuckDBPreparedStatement, "_bind_date", duckdb_prepared_statement__bind_date, 4); rb_define_private_method(cDuckDBPreparedStatement, "_bind_time", duckdb_prepared_statement__bind_time, 5); rb_define_private_method(cDuckDBPreparedStatement, "_bind_timestamp", duckdb_prepared_statement__bind_timestamp, 8); rb_define_private_method(cDuckDBPreparedStatement, "_bind_interval", duckdb_prepared_statement__bind_interval, 4); rb_define_private_method(cDuckDBPreparedStatement, "_bind_hugeint", duckdb_prepared_statement__bind_hugeint, 3); + rb_define_private_method(cDuckDBPreparedStatement, "_bind_decimal", duckdb_prepared_statement__bind_decimal, 5); }