duckdb 0.9.1.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.gitattributes +1 -0
 - data/.github/workflows/test_on_macos.yml +6 -6
 - data/.github/workflows/test_on_ubuntu.yml +6 -6
 - data/.github/workflows/test_on_windows.yml +4 -4
 - data/CHANGELOG.md +11 -0
 - data/Dockerfile +1 -1
 - data/Gemfile.lock +5 -5
 - data/README.md +17 -1
 - data/benchmark/async_query.rb +90 -0
 - data/ext/duckdb/appender.c +5 -5
 - data/ext/duckdb/appender.h +1 -1
 - data/ext/duckdb/blob.c +1 -1
 - data/ext/duckdb/blob.h +1 -4
 - data/ext/duckdb/column.c +2 -2
 - data/ext/duckdb/column.h +2 -2
 - data/ext/duckdb/config.c +1 -1
 - data/ext/duckdb/config.h +1 -1
 - data/ext/duckdb/connection.c +66 -6
 - data/ext/duckdb/connection.h +2 -2
 - data/ext/duckdb/converter.h +1 -1
 - data/ext/duckdb/conveter.c +1 -1
 - data/ext/duckdb/database.c +3 -3
 - data/ext/duckdb/database.h +2 -2
 - data/ext/duckdb/duckdb.c +11 -11
 - data/ext/duckdb/error.c +1 -1
 - data/ext/duckdb/error.h +1 -1
 - data/ext/duckdb/extconf.rb +46 -13
 - data/ext/duckdb/pending_result.c +45 -6
 - data/ext/duckdb/pending_result.h +1 -1
 - data/ext/duckdb/prepared_statement.c +7 -7
 - data/ext/duckdb/prepared_statement.h +1 -1
 - data/ext/duckdb/result.c +112 -70
 - data/ext/duckdb/result.h +2 -2
 - data/ext/duckdb/ruby-duckdb.h +1 -0
 - data/ext/duckdb/util.c +4 -4
 - data/ext/duckdb/util.h +4 -4
 - data/lib/duckdb/appender.rb +1 -10
 - data/lib/duckdb/connection.rb +50 -8
 - data/lib/duckdb/converter.rb +27 -1
 - data/lib/duckdb/prepared_statement.rb +42 -40
 - data/lib/duckdb/result.rb +8 -2
 - data/lib/duckdb/version.rb +1 -1
 - data/sample/async_query.rb +24 -0
 - data/sample/async_query_stream.rb +24 -0
 - metadata +6 -2
 
    
        data/ext/duckdb/extconf.rb
    CHANGED
    
    | 
         @@ -1,31 +1,64 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require 'mkmf'
         
     | 
| 
       2 
4 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
               
     | 
| 
      
 5 
     | 
    
         
            +
            DUCKDB_REQUIRED_VERSION = '0.8.0'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            def check_duckdb_header(header, version)
         
     | 
| 
      
 8 
     | 
    
         
            +
              found = find_header(
         
     | 
| 
      
 9 
     | 
    
         
            +
                header,
         
     | 
| 
      
 10 
     | 
    
         
            +
                '/opt/homebrew/include',
         
     | 
| 
      
 11 
     | 
    
         
            +
                '/opt/homebrew/opt/duckdb/include',
         
     | 
| 
      
 12 
     | 
    
         
            +
                '/opt/local/include'
         
     | 
| 
      
 13 
     | 
    
         
            +
              )
         
     | 
| 
      
 14 
     | 
    
         
            +
              return if found
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              msg = "#{header} is not found. Install #{header} of duckdb >= #{version}."
         
     | 
| 
      
 17 
     | 
    
         
            +
              print_message(msg)
         
     | 
| 
      
 18 
     | 
    
         
            +
              raise msg
         
     | 
| 
       7 
19 
     | 
    
         
             
            end
         
     | 
| 
       8 
20 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
            def check_duckdb_library(func, version)
         
     | 
| 
       10 
     | 
    
         
            -
               
     | 
| 
      
 21 
     | 
    
         
            +
            def check_duckdb_library(library, func, version)
         
     | 
| 
      
 22 
     | 
    
         
            +
              found = find_library(
         
     | 
| 
      
 23 
     | 
    
         
            +
                library,
         
     | 
| 
      
 24 
     | 
    
         
            +
                func,
         
     | 
| 
      
 25 
     | 
    
         
            +
                '/opt/homebrew/lib',
         
     | 
| 
      
 26 
     | 
    
         
            +
                '/opt/homebrew/opt/duckdb/lib',
         
     | 
| 
      
 27 
     | 
    
         
            +
                '/opt/local/lib'
         
     | 
| 
      
 28 
     | 
    
         
            +
              )
         
     | 
| 
      
 29 
     | 
    
         
            +
              return if found
         
     | 
| 
       11 
30 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
               
     | 
| 
       13 
     | 
    
         
            -
               
     | 
| 
       14 
     | 
    
         
            -
               
     | 
| 
       15 
     | 
    
         
            -
              puts msg
         
     | 
| 
       16 
     | 
    
         
            -
              puts '*' * 80
         
     | 
| 
       17 
     | 
    
         
            -
              puts ''
         
     | 
| 
      
 31 
     | 
    
         
            +
              library_name = duckdb_library_name(library)
         
     | 
| 
      
 32 
     | 
    
         
            +
              msg = "#{library_name} is not found. Install #{library_name} of duckdb >= #{version}."
         
     | 
| 
      
 33 
     | 
    
         
            +
              print_message(msg)
         
     | 
| 
       18 
34 
     | 
    
         
             
              raise msg
         
     | 
| 
       19 
35 
     | 
    
         
             
            end
         
     | 
| 
       20 
36 
     | 
    
         | 
| 
      
 37 
     | 
    
         
            +
            def duckdb_library_name(library)
         
     | 
| 
      
 38 
     | 
    
         
            +
              "lib#{library}.(so|dylib|dll)"
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            def print_message(msg)
         
     | 
| 
      
 42 
     | 
    
         
            +
              print <<~END_OF_MESSAGE
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                #{'*' * 80}
         
     | 
| 
      
 45 
     | 
    
         
            +
                #{msg}
         
     | 
| 
      
 46 
     | 
    
         
            +
                #{'*' * 80}
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              END_OF_MESSAGE
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
       21 
51 
     | 
    
         
             
            dir_config('duckdb')
         
     | 
| 
       22 
52 
     | 
    
         | 
| 
      
 53 
     | 
    
         
            +
            check_duckdb_header('duckdb.h', DUCKDB_REQUIRED_VERSION)
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
       23 
55 
     | 
    
         
             
            # check duckdb >= 0.8.0
         
     | 
| 
       24 
     | 
    
         
            -
            check_duckdb_library(' 
     | 
| 
      
 56 
     | 
    
         
            +
            check_duckdb_library('duckdb', 'duckdb_string_is_inlined', DUCKDB_REQUIRED_VERSION)
         
     | 
| 
       25 
57 
     | 
    
         | 
| 
       26 
58 
     | 
    
         
             
            # check duckdb >= 0.9.0
         
     | 
| 
       27 
59 
     | 
    
         
             
            have_func('duckdb_bind_parameter_index', 'duckdb.h')
         
     | 
| 
       28 
60 
     | 
    
         | 
| 
      
 61 
     | 
    
         
            +
            # duckdb_parameter_name is not found on Windows.
         
     | 
| 
       29 
62 
     | 
    
         
             
            have_func('duckdb_parameter_name', 'duckdb.h')
         
     | 
| 
       30 
63 
     | 
    
         | 
| 
       31 
64 
     | 
    
         
             
            create_makefile('duckdb/duckdb_native')
         
     | 
    
        data/ext/duckdb/pending_result.c
    CHANGED
    
    | 
         @@ -5,7 +5,7 @@ static VALUE cDuckDBPendingResult; 
     | 
|
| 
       5 
5 
     | 
    
         
             
            static void deallocate(void *ctx);
         
     | 
| 
       6 
6 
     | 
    
         
             
            static VALUE allocate(VALUE klass);
         
     | 
| 
       7 
7 
     | 
    
         
             
            static size_t memsize(const void *p);
         
     | 
| 
       8 
     | 
    
         
            -
            static VALUE duckdb_pending_result_initialize(VALUE  
     | 
| 
      
 8 
     | 
    
         
            +
            static VALUE duckdb_pending_result_initialize(int argc, VALUE *args, VALUE self);
         
     | 
| 
       9 
9 
     | 
    
         
             
            static VALUE duckdb_pending_result_execute_task(VALUE self);
         
     | 
| 
       10 
10 
     | 
    
         
             
            static VALUE duckdb_pending_result_execute_pending(VALUE self);
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
         @@ -38,16 +38,43 @@ static size_t memsize(const void *p) { 
     | 
|
| 
       38 
38 
     | 
    
         
             
                return sizeof(rubyDuckDBPendingResult);
         
     | 
| 
       39 
39 
     | 
    
         
             
            }
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
            static VALUE duckdb_pending_result_initialize(VALUE  
     | 
| 
      
 41 
     | 
    
         
            +
            static VALUE duckdb_pending_result_initialize(int argc, VALUE *argv, VALUE self) {
         
     | 
| 
      
 42 
     | 
    
         
            +
                VALUE oDuckDBPreparedStatement;
         
     | 
| 
      
 43 
     | 
    
         
            +
                VALUE streaming_p = Qfalse;
         
     | 
| 
      
 44 
     | 
    
         
            +
                duckdb_state state;
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                rb_scan_args(argc, argv, "11", &oDuckDBPreparedStatement, &streaming_p);
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                if (rb_obj_is_kind_of(oDuckDBPreparedStatement, cDuckDBPreparedStatement) != Qtrue) {
         
     | 
| 
      
 49 
     | 
    
         
            +
                    rb_raise(rb_eTypeError, "1st argument must be DuckDB::PreparedStatement");
         
     | 
| 
      
 50 
     | 
    
         
            +
                }
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
       42 
52 
     | 
    
         
             
                rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
         
     | 
| 
       43 
53 
     | 
    
         
             
                rubyDuckDBPreparedStatement *stmt = get_struct_prepared_statement(oDuckDBPreparedStatement);
         
     | 
| 
       44 
54 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
                if ( 
     | 
| 
      
 55 
     | 
    
         
            +
                if (!NIL_P(streaming_p) && streaming_p == Qtrue) {
         
     | 
| 
      
 56 
     | 
    
         
            +
                    state = duckdb_pending_prepared_streaming(stmt->prepared_statement, &(ctx->pending_result));
         
     | 
| 
      
 57 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 58 
     | 
    
         
            +
                    state = duckdb_pending_prepared(stmt->prepared_statement, &(ctx->pending_result));
         
     | 
| 
      
 59 
     | 
    
         
            +
                }
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                if (state == DuckDBError) {
         
     | 
| 
       46 
62 
     | 
    
         
             
                    rb_raise(eDuckDBError, "%s", duckdb_pending_error(ctx->pending_result));
         
     | 
| 
       47 
63 
     | 
    
         
             
                }
         
     | 
| 
       48 
64 
     | 
    
         
             
                return self;
         
     | 
| 
       49 
65 
     | 
    
         
             
            }
         
     | 
| 
       50 
66 
     | 
    
         | 
| 
      
 67 
     | 
    
         
            +
            /*
         
     | 
| 
      
 68 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 69 
     | 
    
         
            +
             *   pending_result.execute_task -> nil
         
     | 
| 
      
 70 
     | 
    
         
            +
             *
         
     | 
| 
      
 71 
     | 
    
         
            +
             * Executes the task in the pending result.
         
     | 
| 
      
 72 
     | 
    
         
            +
             *
         
     | 
| 
      
 73 
     | 
    
         
            +
             *  db = DuckDB::Database.open
         
     | 
| 
      
 74 
     | 
    
         
            +
             *  conn = db.connect
         
     | 
| 
      
 75 
     | 
    
         
            +
             *  pending_result = conn.async_query("slow query")
         
     | 
| 
      
 76 
     | 
    
         
            +
             *  pending_result.execute_task
         
     | 
| 
      
 77 
     | 
    
         
            +
             */
         
     | 
| 
       51 
78 
     | 
    
         
             
            static VALUE duckdb_pending_result_execute_task(VALUE self) {
         
     | 
| 
       52 
79 
     | 
    
         
             
                rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
         
     | 
| 
       53 
80 
     | 
    
         
             
                ctx->state = duckdb_pending_execute_task(ctx->pending_result);
         
     | 
| 
         @@ -61,10 +88,22 @@ static VALUE duckdb_pending_result_execution_finished_p(VALUE self) { 
     | 
|
| 
       61 
88 
     | 
    
         
             
            }
         
     | 
| 
       62 
89 
     | 
    
         
             
            #endif
         
     | 
| 
       63 
90 
     | 
    
         | 
| 
      
 91 
     | 
    
         
            +
            /*
         
     | 
| 
      
 92 
     | 
    
         
            +
             * call-seq:
         
     | 
| 
      
 93 
     | 
    
         
            +
             *   pending_result.execute_pending -> DuckDB::Result
         
     | 
| 
      
 94 
     | 
    
         
            +
             *
         
     | 
| 
      
 95 
     | 
    
         
            +
             * Get DuckDB::Result object after query execution finished.
         
     | 
| 
      
 96 
     | 
    
         
            +
             *
         
     | 
| 
      
 97 
     | 
    
         
            +
             *  db = DuckDB::Database.open
         
     | 
| 
      
 98 
     | 
    
         
            +
             *  conn = db.connect
         
     | 
| 
      
 99 
     | 
    
         
            +
             *  pending_result = conn.async_query("slow query")
         
     | 
| 
      
 100 
     | 
    
         
            +
             *  pending_result.execute_task while pending_result.state != :ready
         
     | 
| 
      
 101 
     | 
    
         
            +
             *  result = pending_result.execute_pending # => DuckDB::Result
         
     | 
| 
      
 102 
     | 
    
         
            +
             */
         
     | 
| 
       64 
103 
     | 
    
         
             
            static VALUE duckdb_pending_result_execute_pending(VALUE self) {
         
     | 
| 
       65 
104 
     | 
    
         
             
                rubyDuckDBPendingResult *ctx;
         
     | 
| 
       66 
105 
     | 
    
         
             
                rubyDuckDBResult *ctxr;
         
     | 
| 
       67 
     | 
    
         
            -
                VALUE result =  
     | 
| 
      
 106 
     | 
    
         
            +
                VALUE result = rbduckdb_create_result();
         
     | 
| 
       68 
107 
     | 
    
         | 
| 
       69 
108 
     | 
    
         
             
                TypedData_Get_Struct(self, rubyDuckDBPendingResult, &pending_result_data_type, ctx);
         
     | 
| 
       70 
109 
     | 
    
         
             
                ctxr = get_struct_result(result);
         
     | 
| 
         @@ -85,11 +124,11 @@ rubyDuckDBPendingResult *get_struct_pending_result(VALUE obj) { 
     | 
|
| 
       85 
124 
     | 
    
         
             
                return ctx;
         
     | 
| 
       86 
125 
     | 
    
         
             
            }
         
     | 
| 
       87 
126 
     | 
    
         | 
| 
       88 
     | 
    
         
            -
            void  
     | 
| 
      
 127 
     | 
    
         
            +
            void rbduckdb_init_duckdb_pending_result(void) {
         
     | 
| 
       89 
128 
     | 
    
         
             
                cDuckDBPendingResult = rb_define_class_under(mDuckDB, "PendingResult", rb_cObject);
         
     | 
| 
       90 
129 
     | 
    
         
             
                rb_define_alloc_func(cDuckDBPendingResult, allocate);
         
     | 
| 
       91 
130 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
                rb_define_method(cDuckDBPendingResult, "initialize", duckdb_pending_result_initialize, 1);
         
     | 
| 
      
 131 
     | 
    
         
            +
                rb_define_method(cDuckDBPendingResult, "initialize", duckdb_pending_result_initialize, -1);
         
     | 
| 
       93 
132 
     | 
    
         
             
                rb_define_method(cDuckDBPendingResult, "execute_task", duckdb_pending_result_execute_task, 0);
         
     | 
| 
       94 
133 
     | 
    
         
             
                rb_define_method(cDuckDBPendingResult, "execute_pending", duckdb_pending_result_execute_pending, 0);
         
     | 
| 
       95 
134 
     | 
    
         | 
    
        data/ext/duckdb/pending_result.h
    CHANGED
    
    | 
         @@ -9,5 +9,5 @@ struct _rubyDuckDBPendingResult { 
     | 
|
| 
       9 
9 
     | 
    
         
             
            typedef struct _rubyDuckDBPendingResult rubyDuckDBPendingResult;
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
            rubyDuckDBPendingResult *get_struct_pending_result(VALUE obj);
         
     | 
| 
       12 
     | 
    
         
            -
            void  
     | 
| 
      
 12 
     | 
    
         
            +
            void rbduckdb_init_duckdb_pending_result(void);
         
     | 
| 
       13 
13 
     | 
    
         
             
            #endif
         
     | 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #include "ruby-duckdb.h"
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            VALUE cDuckDBPreparedStatement;
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            static void deallocate(void *ctx);
         
     | 
| 
       6 
6 
     | 
    
         
             
            static VALUE allocate(VALUE klass);
         
     | 
| 
         @@ -83,7 +83,7 @@ static VALUE duckdb_prepared_statement_nparams(VALUE self) { 
     | 
|
| 
       83 
83 
     | 
    
         
             
            static VALUE duckdb_prepared_statement_execute(VALUE self) {
         
     | 
| 
       84 
84 
     | 
    
         
             
                rubyDuckDBPreparedStatement *ctx;
         
     | 
| 
       85 
85 
     | 
    
         
             
                rubyDuckDBResult *ctxr;
         
     | 
| 
       86 
     | 
    
         
            -
                VALUE result =  
     | 
| 
      
 86 
     | 
    
         
            +
                VALUE result = rbduckdb_create_result();
         
     | 
| 
       87 
87 
     | 
    
         | 
| 
       88 
88 
     | 
    
         
             
                TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
         
     | 
| 
       89 
89 
     | 
    
         
             
                ctxr = get_struct_result(result);
         
     | 
| 
         @@ -268,7 +268,7 @@ static VALUE duckdb_prepared_statement__bind_date(VALUE self, VALUE vidx, VALUE 
     | 
|
| 
       268 
268 
     | 
    
         
             
                duckdb_date dt;
         
     | 
| 
       269 
269 
     | 
    
         
             
                idx_t idx = check_index(vidx);
         
     | 
| 
       270 
270 
     | 
    
         | 
| 
       271 
     | 
    
         
            -
                dt =  
     | 
| 
      
 271 
     | 
    
         
            +
                dt = rbduckdb_to_duckdb_date_from_value(year, month, day);
         
     | 
| 
       272 
272 
     | 
    
         | 
| 
       273 
273 
     | 
    
         
             
                TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
         
     | 
| 
       274 
274 
     | 
    
         | 
| 
         @@ -285,7 +285,7 @@ static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE 
     | 
|
| 
       285 
285 
     | 
    
         | 
| 
       286 
286 
     | 
    
         
             
                idx_t idx = check_index(vidx);
         
     | 
| 
       287 
287 
     | 
    
         | 
| 
       288 
     | 
    
         
            -
                time =  
     | 
| 
      
 288 
     | 
    
         
            +
                time = rbduckdb_to_duckdb_time_from_value(hour, min, sec, micros);
         
     | 
| 
       289 
289 
     | 
    
         | 
| 
       290 
290 
     | 
    
         
             
                TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
         
     | 
| 
       291 
291 
     | 
    
         | 
| 
         @@ -301,7 +301,7 @@ static VALUE duckdb_prepared_statement__bind_timestamp(VALUE self, VALUE vidx, V 
     | 
|
| 
       301 
301 
     | 
    
         
             
                rubyDuckDBPreparedStatement *ctx;
         
     | 
| 
       302 
302 
     | 
    
         
             
                idx_t idx = check_index(vidx);
         
     | 
| 
       303 
303 
     | 
    
         | 
| 
       304 
     | 
    
         
            -
                timestamp =  
     | 
| 
      
 304 
     | 
    
         
            +
                timestamp = rbduckdb_to_duckdb_timestamp_from_value(year, month, day, hour, min, sec, micros);
         
     | 
| 
       305 
305 
     | 
    
         
             
                TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
         
     | 
| 
       306 
306 
     | 
    
         | 
| 
       307 
307 
     | 
    
         
             
                if (duckdb_bind_timestamp(ctx->prepared_statement, idx, timestamp) == DuckDBError) {
         
     | 
| 
         @@ -317,7 +317,7 @@ static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VA 
     | 
|
| 
       317 
317 
     | 
    
         | 
| 
       318 
318 
     | 
    
         
             
                TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
         
     | 
| 
       319 
319 
     | 
    
         | 
| 
       320 
     | 
    
         
            -
                 
     | 
| 
      
 320 
     | 
    
         
            +
                rbduckdb_to_duckdb_interval_from_value(&interval, months, days, micros);
         
     | 
| 
       321 
321 
     | 
    
         | 
| 
       322 
322 
     | 
    
         
             
                if (duckdb_bind_interval(ctx->prepared_statement, idx, interval) == DuckDBError) {
         
     | 
| 
       323 
323 
     | 
    
         
             
                    rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx);
         
     | 
| 
         @@ -347,7 +347,7 @@ rubyDuckDBPreparedStatement *get_struct_prepared_statement(VALUE self) { 
     | 
|
| 
       347 
347 
     | 
    
         
             
                return ctx;
         
     | 
| 
       348 
348 
     | 
    
         
             
            }
         
     | 
| 
       349 
349 
     | 
    
         | 
| 
       350 
     | 
    
         
            -
            void  
     | 
| 
      
 350 
     | 
    
         
            +
            void rbduckdb_init_duckdb_prepared_statement(void) {
         
     | 
| 
       351 
351 
     | 
    
         
             
                cDuckDBPreparedStatement = rb_define_class_under(mDuckDB, "PreparedStatement", rb_cObject);
         
     | 
| 
       352 
352 
     | 
    
         | 
| 
       353 
353 
     | 
    
         
             
                rb_define_alloc_func(cDuckDBPreparedStatement, allocate);
         
     | 
| 
         @@ -9,6 +9,6 @@ struct _rubyDuckDBPreparedStatement { 
     | 
|
| 
       9 
9 
     | 
    
         
             
            typedef struct _rubyDuckDBPreparedStatement rubyDuckDBPreparedStatement;
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
            rubyDuckDBPreparedStatement *get_struct_prepared_statement(VALUE self);
         
     | 
| 
       12 
     | 
    
         
            -
            void  
     | 
| 
      
 12 
     | 
    
         
            +
            void rbduckdb_init_duckdb_prepared_statement(void);
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
            #endif
         
     | 
    
        data/ext/duckdb/result.c
    CHANGED
    
    | 
         @@ -19,6 +19,11 @@ static VALUE duckdb_result_column_count(VALUE oDuckDBResult); 
     | 
|
| 
       19 
19 
     | 
    
         
             
            static VALUE duckdb_result_row_count(VALUE oDuckDBResult);
         
     | 
| 
       20 
20 
     | 
    
         
             
            static VALUE duckdb_result_rows_changed(VALUE oDuckDBResult);
         
     | 
| 
       21 
21 
     | 
    
         
             
            static VALUE duckdb_result_columns(VALUE oDuckDBResult);
         
     | 
| 
      
 22 
     | 
    
         
            +
            static VALUE duckdb_result_streaming_p(VALUE oDuckDBResult);
         
     | 
| 
      
 23 
     | 
    
         
            +
            static VALUE duckdb_result_chunk_each(VALUE oDuckDBResult);
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            static VALUE duckdb_result__chunk_stream(VALUE oDuckDBResult);
         
     | 
| 
      
 26 
     | 
    
         
            +
            static void yield_rows(duckdb_data_chunk chunk, idx_t col_count);
         
     | 
| 
       22 
27 
     | 
    
         
             
            static VALUE duckdb_result__column_type(VALUE oDuckDBResult, VALUE col_idx);
         
     | 
| 
       23 
28 
     | 
    
         
             
            static VALUE duckdb_result__is_null(VALUE oDuckDBResult, VALUE row_idx, VALUE col_idx);
         
     | 
| 
       24 
29 
     | 
    
         
             
            static VALUE duckdb_result__to_boolean(VALUE oDuckDBResult, VALUE row_idx, VALUE col_idx);
         
     | 
| 
         @@ -50,7 +55,6 @@ static VALUE vector_map(duckdb_logical_type ty, duckdb_vector vector, idx_t row_ 
     | 
|
| 
       50 
55 
     | 
    
         
             
            static VALUE vector_struct(duckdb_logical_type ty, duckdb_vector vector, idx_t row_idx);
         
     | 
| 
       51 
56 
     | 
    
         
             
            static VALUE vector_uuid(void* vector_data, idx_t row_idx);
         
     | 
| 
       52 
57 
     | 
    
         
             
            static VALUE vector_value(duckdb_vector vector, idx_t row_idx);
         
     | 
| 
       53 
     | 
    
         
            -
            static VALUE duckdb_result_chunk_each(VALUE oDuckDBResult);
         
     | 
| 
       54 
58 
     | 
    
         | 
| 
       55 
59 
     | 
    
         
             
            static const rb_data_type_t result_data_type = {
         
     | 
| 
       56 
60 
     | 
    
         
             
                "DuckDB/Result",
         
     | 
| 
         @@ -229,12 +233,85 @@ static VALUE duckdb_result_columns(VALUE oDuckDBResult) { 
     | 
|
| 
       229 
233 
     | 
    
         | 
| 
       230 
234 
     | 
    
         
             
                VALUE ary = rb_ary_new2(column_count);
         
     | 
| 
       231 
235 
     | 
    
         
             
                for(col_idx = 0; col_idx < column_count; col_idx++) {
         
     | 
| 
       232 
     | 
    
         
            -
                    VALUE column =  
     | 
| 
      
 236 
     | 
    
         
            +
                    VALUE column = rbduckdb_create_column(oDuckDBResult, col_idx);
         
     | 
| 
       233 
237 
     | 
    
         
             
                    rb_ary_store(ary, col_idx, column);
         
     | 
| 
       234 
238 
     | 
    
         
             
                }
         
     | 
| 
       235 
239 
     | 
    
         
             
                return ary;
         
     | 
| 
       236 
240 
     | 
    
         
             
            }
         
     | 
| 
       237 
241 
     | 
    
         | 
| 
      
 242 
     | 
    
         
            +
            /*
         
     | 
| 
      
 243 
     | 
    
         
            +
             *  call-seq:
         
     | 
| 
      
 244 
     | 
    
         
            +
             *    result.streaming? -> Boolean
         
     | 
| 
      
 245 
     | 
    
         
            +
             *
         
     | 
| 
      
 246 
     | 
    
         
            +
             *  Returns true if the result is streaming, otherwise false.
         
     | 
| 
      
 247 
     | 
    
         
            +
             *
         
     | 
| 
      
 248 
     | 
    
         
            +
             */
         
     | 
| 
      
 249 
     | 
    
         
            +
            static VALUE duckdb_result_streaming_p(VALUE oDuckDBResult) {
         
     | 
| 
      
 250 
     | 
    
         
            +
                rubyDuckDBResult *ctx;
         
     | 
| 
      
 251 
     | 
    
         
            +
                TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
         
     | 
| 
      
 252 
     | 
    
         
            +
                return duckdb_result_is_streaming(ctx->result) ? Qtrue : Qfalse;
         
     | 
| 
      
 253 
     | 
    
         
            +
            }
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
      
 255 
     | 
    
         
            +
            static VALUE duckdb_result_chunk_each(VALUE oDuckDBResult) {
         
     | 
| 
      
 256 
     | 
    
         
            +
                rubyDuckDBResult *ctx;
         
     | 
| 
      
 257 
     | 
    
         
            +
                idx_t col_count;
         
     | 
| 
      
 258 
     | 
    
         
            +
                idx_t chunk_count;
         
     | 
| 
      
 259 
     | 
    
         
            +
                idx_t chunk_idx;
         
     | 
| 
      
 260 
     | 
    
         
            +
                duckdb_data_chunk chunk;
         
     | 
| 
      
 261 
     | 
    
         
            +
             
     | 
| 
      
 262 
     | 
    
         
            +
                TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                col_count = duckdb_column_count(&(ctx->result));
         
     | 
| 
      
 265 
     | 
    
         
            +
                chunk_count = duckdb_result_chunk_count(ctx->result);
         
     | 
| 
      
 266 
     | 
    
         
            +
             
     | 
| 
      
 267 
     | 
    
         
            +
                RETURN_ENUMERATOR(oDuckDBResult, 0, 0);
         
     | 
| 
      
 268 
     | 
    
         
            +
             
     | 
| 
      
 269 
     | 
    
         
            +
                for (chunk_idx = 0; chunk_idx < chunk_count; chunk_idx++) {
         
     | 
| 
      
 270 
     | 
    
         
            +
                    chunk = duckdb_result_get_chunk(ctx->result, chunk_idx);
         
     | 
| 
      
 271 
     | 
    
         
            +
                    yield_rows(chunk, col_count);
         
     | 
| 
      
 272 
     | 
    
         
            +
                    duckdb_destroy_data_chunk(&chunk);
         
     | 
| 
      
 273 
     | 
    
         
            +
                }
         
     | 
| 
      
 274 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 275 
     | 
    
         
            +
            }
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
      
 277 
     | 
    
         
            +
            static VALUE duckdb_result__chunk_stream(VALUE oDuckDBResult) {
         
     | 
| 
      
 278 
     | 
    
         
            +
                rubyDuckDBResult *ctx;
         
     | 
| 
      
 279 
     | 
    
         
            +
                duckdb_data_chunk chunk;
         
     | 
| 
      
 280 
     | 
    
         
            +
                idx_t col_count;
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
      
 282 
     | 
    
         
            +
                TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
         
     | 
| 
      
 283 
     | 
    
         
            +
             
     | 
| 
      
 284 
     | 
    
         
            +
                RETURN_ENUMERATOR(oDuckDBResult, 0, 0);
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
      
 286 
     | 
    
         
            +
                col_count = duckdb_column_count(&(ctx->result));
         
     | 
| 
      
 287 
     | 
    
         
            +
             
     | 
| 
      
 288 
     | 
    
         
            +
                while((chunk = duckdb_stream_fetch_chunk(ctx->result)) != NULL) {
         
     | 
| 
      
 289 
     | 
    
         
            +
                    yield_rows(chunk, col_count);
         
     | 
| 
      
 290 
     | 
    
         
            +
                    duckdb_destroy_data_chunk(&chunk);
         
     | 
| 
      
 291 
     | 
    
         
            +
                }
         
     | 
| 
      
 292 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 293 
     | 
    
         
            +
            }
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
      
 295 
     | 
    
         
            +
            static void yield_rows(duckdb_data_chunk chunk, idx_t col_count) {
         
     | 
| 
      
 296 
     | 
    
         
            +
                idx_t row_count;
         
     | 
| 
      
 297 
     | 
    
         
            +
                idx_t row_idx;
         
     | 
| 
      
 298 
     | 
    
         
            +
                idx_t col_idx;
         
     | 
| 
      
 299 
     | 
    
         
            +
                duckdb_vector vector;
         
     | 
| 
      
 300 
     | 
    
         
            +
                VALUE row;
         
     | 
| 
      
 301 
     | 
    
         
            +
                VALUE val;
         
     | 
| 
      
 302 
     | 
    
         
            +
             
     | 
| 
      
 303 
     | 
    
         
            +
                row_count = duckdb_data_chunk_get_size(chunk);
         
     | 
| 
      
 304 
     | 
    
         
            +
                for (row_idx = 0; row_idx < row_count; row_idx++) {
         
     | 
| 
      
 305 
     | 
    
         
            +
                    row = rb_ary_new2(col_count);
         
     | 
| 
      
 306 
     | 
    
         
            +
                    for (col_idx = 0; col_idx < col_count; col_idx++) {
         
     | 
| 
      
 307 
     | 
    
         
            +
                        vector = duckdb_data_chunk_get_vector(chunk, col_idx);
         
     | 
| 
      
 308 
     | 
    
         
            +
                        val = vector_value(vector, row_idx);
         
     | 
| 
      
 309 
     | 
    
         
            +
                        rb_ary_store(row, col_idx, val);
         
     | 
| 
      
 310 
     | 
    
         
            +
                    }
         
     | 
| 
      
 311 
     | 
    
         
            +
                    rb_yield(row);
         
     | 
| 
      
 312 
     | 
    
         
            +
                }
         
     | 
| 
      
 313 
     | 
    
         
            +
            }
         
     | 
| 
      
 314 
     | 
    
         
            +
             
     | 
| 
       238 
315 
     | 
    
         
             
            static VALUE duckdb_result__column_type(VALUE oDuckDBResult, VALUE col_idx) {
         
     | 
| 
       239 
316 
     | 
    
         
             
                rubyDuckDBResult *ctx;
         
     | 
| 
       240 
317 
     | 
    
         
             
                TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
         
     | 
| 
         @@ -397,7 +474,7 @@ static VALUE duckdb_result__enum_dictionary_value(VALUE oDuckDBResult, VALUE col 
     | 
|
| 
       397 
474 
     | 
    
         
             
                return value;
         
     | 
| 
       398 
475 
     | 
    
         
             
            }
         
     | 
| 
       399 
476 
     | 
    
         | 
| 
       400 
     | 
    
         
            -
            VALUE  
     | 
| 
      
 477 
     | 
    
         
            +
            VALUE rbduckdb_create_result(void) {
         
     | 
| 
       401 
478 
     | 
    
         
             
                return allocate(cDuckDBResult);
         
     | 
| 
       402 
479 
     | 
    
         
             
            }
         
     | 
| 
       403 
480 
     | 
    
         | 
| 
         @@ -405,32 +482,32 @@ static VALUE vector_date(void *vector_data, idx_t row_idx) { 
     | 
|
| 
       405 
482 
     | 
    
         
             
                duckdb_date_struct date = duckdb_from_date(((duckdb_date *) vector_data)[row_idx]);
         
     | 
| 
       406 
483 
     | 
    
         | 
| 
       407 
484 
     | 
    
         
             
                return rb_funcall(mDuckDBConverter, rb_intern("_to_date"), 3,
         
     | 
| 
       408 
     | 
    
         
            -
             
     | 
| 
       409 
     | 
    
         
            -
             
     | 
| 
       410 
     | 
    
         
            -
             
     | 
| 
       411 
     | 
    
         
            -
             
     | 
| 
      
 485 
     | 
    
         
            +
                                  INT2FIX(date.year),
         
     | 
| 
      
 486 
     | 
    
         
            +
                                  INT2FIX(date.month),
         
     | 
| 
      
 487 
     | 
    
         
            +
                                  INT2FIX(date.day)
         
     | 
| 
      
 488 
     | 
    
         
            +
                                  );
         
     | 
| 
       412 
489 
     | 
    
         
             
            }
         
     | 
| 
       413 
490 
     | 
    
         | 
| 
       414 
491 
     | 
    
         
             
            static VALUE vector_timestamp(void* vector_data, idx_t row_idx) {
         
     | 
| 
       415 
492 
     | 
    
         
             
                duckdb_timestamp_struct data = duckdb_from_timestamp(((duckdb_timestamp *)vector_data)[row_idx]);
         
     | 
| 
       416 
493 
     | 
    
         
             
                return rb_funcall(mDuckDBConverter, rb_intern("_to_time"), 7,
         
     | 
| 
       417 
     | 
    
         
            -
             
     | 
| 
       418 
     | 
    
         
            -
             
     | 
| 
       419 
     | 
    
         
            -
             
     | 
| 
       420 
     | 
    
         
            -
             
     | 
| 
       421 
     | 
    
         
            -
             
     | 
| 
       422 
     | 
    
         
            -
             
     | 
| 
       423 
     | 
    
         
            -
             
     | 
| 
       424 
     | 
    
         
            -
             
     | 
| 
      
 494 
     | 
    
         
            +
                                  INT2FIX(data.date.year),
         
     | 
| 
      
 495 
     | 
    
         
            +
                                  INT2FIX(data.date.month),
         
     | 
| 
      
 496 
     | 
    
         
            +
                                  INT2FIX(data.date.day),
         
     | 
| 
      
 497 
     | 
    
         
            +
                                  INT2FIX(data.time.hour),
         
     | 
| 
      
 498 
     | 
    
         
            +
                                  INT2FIX(data.time.min),
         
     | 
| 
      
 499 
     | 
    
         
            +
                                  INT2FIX(data.time.sec),
         
     | 
| 
      
 500 
     | 
    
         
            +
                                  INT2NUM(data.time.micros)
         
     | 
| 
      
 501 
     | 
    
         
            +
                                  );
         
     | 
| 
       425 
502 
     | 
    
         
             
            }
         
     | 
| 
       426 
503 
     | 
    
         | 
| 
       427 
504 
     | 
    
         
             
            static VALUE vector_interval(void* vector_data, idx_t row_idx) {
         
     | 
| 
       428 
505 
     | 
    
         
             
                duckdb_interval data = ((duckdb_interval *)vector_data)[row_idx];
         
     | 
| 
       429 
506 
     | 
    
         
             
                return rb_funcall(mDuckDBConverter, rb_intern("_to_interval_from_vector"), 3,
         
     | 
| 
       430 
     | 
    
         
            -
             
     | 
| 
       431 
     | 
    
         
            -
             
     | 
| 
       432 
     | 
    
         
            -
             
     | 
| 
       433 
     | 
    
         
            -
             
     | 
| 
      
 507 
     | 
    
         
            +
                                  INT2NUM(data.months),
         
     | 
| 
      
 508 
     | 
    
         
            +
                                  INT2NUM(data.days),
         
     | 
| 
      
 509 
     | 
    
         
            +
                                  LL2NUM(data.micros)
         
     | 
| 
      
 510 
     | 
    
         
            +
                                  );
         
     | 
| 
       434 
511 
     | 
    
         
             
            }
         
     | 
| 
       435 
512 
     | 
    
         | 
| 
       436 
513 
     | 
    
         
             
            static VALUE vector_blob(void* vector_data, idx_t row_idx) {
         
     | 
| 
         @@ -454,9 +531,9 @@ static VALUE vector_varchar(void* vector_data, idx_t row_idx) { 
     | 
|
| 
       454 
531 
     | 
    
         
             
            static VALUE vector_hugeint(void* vector_data, idx_t row_idx) {
         
     | 
| 
       455 
532 
     | 
    
         
             
                duckdb_hugeint hugeint = ((duckdb_hugeint *)vector_data)[row_idx];
         
     | 
| 
       456 
533 
     | 
    
         
             
                return rb_funcall(mDuckDBConverter, rb_intern("_to_hugeint_from_vector"), 2,
         
     | 
| 
       457 
     | 
    
         
            -
             
     | 
| 
       458 
     | 
    
         
            -
             
     | 
| 
       459 
     | 
    
         
            -
             
     | 
| 
      
 534 
     | 
    
         
            +
                                  ULL2NUM(hugeint.lower),
         
     | 
| 
      
 535 
     | 
    
         
            +
                                  LL2NUM(hugeint.upper)
         
     | 
| 
      
 536 
     | 
    
         
            +
                                  );
         
     | 
| 
       460 
537 
     | 
    
         
             
            }
         
     | 
| 
       461 
538 
     | 
    
         | 
| 
       462 
539 
     | 
    
         
             
            static VALUE vector_decimal(duckdb_logical_type ty, void* vector_data, idx_t row_idx) {
         
     | 
| 
         @@ -477,11 +554,11 @@ static VALUE vector_decimal(duckdb_logical_type ty, void* vector_data, idx_t row 
     | 
|
| 
       477 
554 
     | 
    
         
             
                }
         
     | 
| 
       478 
555 
     | 
    
         | 
| 
       479 
556 
     | 
    
         
             
                return rb_funcall(mDuckDBConverter, rb_intern("_to_decimal_from_vector"), 4,
         
     | 
| 
       480 
     | 
    
         
            -
             
     | 
| 
       481 
     | 
    
         
            -
             
     | 
| 
       482 
     | 
    
         
            -
             
     | 
| 
       483 
     | 
    
         
            -
             
     | 
| 
       484 
     | 
    
         
            -
             
     | 
| 
      
 557 
     | 
    
         
            +
                                  INT2FIX(width),
         
     | 
| 
      
 558 
     | 
    
         
            +
                                  INT2FIX(scale),
         
     | 
| 
      
 559 
     | 
    
         
            +
                                  ULL2NUM(value.lower),
         
     | 
| 
      
 560 
     | 
    
         
            +
                                  LL2NUM(value.upper)
         
     | 
| 
      
 561 
     | 
    
         
            +
                                  );
         
     | 
| 
       485 
562 
     | 
    
         
             
            }
         
     | 
| 
       486 
563 
     | 
    
         | 
| 
       487 
564 
     | 
    
         
             
            static VALUE vector_enum(duckdb_logical_type ty, void* vector_data, idx_t row_idx) {
         
     | 
| 
         @@ -577,9 +654,9 @@ static VALUE vector_struct(duckdb_logical_type ty, duckdb_vector vector, idx_t r 
     | 
|
| 
       577 
654 
     | 
    
         
             
            static VALUE vector_uuid(void* vector_data, idx_t row_idx) {
         
     | 
| 
       578 
655 
     | 
    
         
             
                duckdb_hugeint hugeint = ((duckdb_hugeint *)vector_data)[row_idx];
         
     | 
| 
       579 
656 
     | 
    
         
             
                return rb_funcall(mDuckDBConverter, rb_intern("_to_uuid_from_vector"), 2,
         
     | 
| 
       580 
     | 
    
         
            -
             
     | 
| 
       581 
     | 
    
         
            -
             
     | 
| 
       582 
     | 
    
         
            -
             
     | 
| 
      
 657 
     | 
    
         
            +
                                  ULL2NUM(hugeint.lower),
         
     | 
| 
      
 658 
     | 
    
         
            +
                                  LL2NUM(hugeint.upper)
         
     | 
| 
      
 659 
     | 
    
         
            +
                                  );
         
     | 
| 
       583 
660 
     | 
    
         
             
            }
         
     | 
| 
       584 
661 
     | 
    
         | 
| 
       585 
662 
     | 
    
         
             
            static VALUE vector_value(duckdb_vector vector, idx_t row_idx) {
         
     | 
| 
         @@ -617,7 +694,7 @@ static VALUE vector_value(duckdb_vector vector, idx_t row_idx) { 
     | 
|
| 
       617 
694 
     | 
    
         
             
                    case DUCKDB_TYPE_BIGINT:
         
     | 
| 
       618 
695 
     | 
    
         
             
                        obj = LL2NUM(((int64_t *) vector_data)[row_idx]);
         
     | 
| 
       619 
696 
     | 
    
         
             
                        break;
         
     | 
| 
       620 
     | 
    
         
            -
             
     | 
| 
      
 697 
     | 
    
         
            +
                    case DUCKDB_TYPE_UTINYINT:
         
     | 
| 
       621 
698 
     | 
    
         
             
                        obj = INT2FIX(((uint8_t *) vector_data)[row_idx]);
         
     | 
| 
       622 
699 
     | 
    
         
             
                        break;
         
     | 
| 
       623 
700 
     | 
    
         
             
                    case DUCKDB_TYPE_USMALLINT:
         
     | 
| 
         @@ -680,44 +757,7 @@ static VALUE vector_value(duckdb_vector vector, idx_t row_idx) { 
     | 
|
| 
       680 
757 
     | 
    
         
             
                return obj;
         
     | 
| 
       681 
758 
     | 
    
         
             
            }
         
     | 
| 
       682 
759 
     | 
    
         | 
| 
       683 
     | 
    
         
            -
             
     | 
| 
       684 
     | 
    
         
            -
                rubyDuckDBResult *ctx;
         
     | 
| 
       685 
     | 
    
         
            -
                VALUE row;
         
     | 
| 
       686 
     | 
    
         
            -
                idx_t col_count;
         
     | 
| 
       687 
     | 
    
         
            -
                idx_t row_count;
         
     | 
| 
       688 
     | 
    
         
            -
                idx_t chunk_count;
         
     | 
| 
       689 
     | 
    
         
            -
                idx_t col_idx;
         
     | 
| 
       690 
     | 
    
         
            -
                idx_t row_idx;
         
     | 
| 
       691 
     | 
    
         
            -
                idx_t chunk_idx;
         
     | 
| 
       692 
     | 
    
         
            -
                duckdb_data_chunk chunk;
         
     | 
| 
       693 
     | 
    
         
            -
                duckdb_vector vector;
         
     | 
| 
       694 
     | 
    
         
            -
                VALUE val;
         
     | 
| 
       695 
     | 
    
         
            -
             
     | 
| 
       696 
     | 
    
         
            -
                TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
         
     | 
| 
       697 
     | 
    
         
            -
             
     | 
| 
       698 
     | 
    
         
            -
                col_count = duckdb_column_count(&(ctx->result));
         
     | 
| 
       699 
     | 
    
         
            -
                chunk_count = duckdb_result_chunk_count(ctx->result);
         
     | 
| 
       700 
     | 
    
         
            -
             
     | 
| 
       701 
     | 
    
         
            -
                RETURN_ENUMERATOR(oDuckDBResult, 0, 0);
         
     | 
| 
       702 
     | 
    
         
            -
             
     | 
| 
       703 
     | 
    
         
            -
                for (chunk_idx = 0; chunk_idx < chunk_count; chunk_idx++) {
         
     | 
| 
       704 
     | 
    
         
            -
                    chunk = duckdb_result_get_chunk(ctx->result, chunk_idx);
         
     | 
| 
       705 
     | 
    
         
            -
                    row_count = duckdb_data_chunk_get_size(chunk);
         
     | 
| 
       706 
     | 
    
         
            -
                    for (row_idx = 0; row_idx < row_count; row_idx++) {
         
     | 
| 
       707 
     | 
    
         
            -
                        row = rb_ary_new2(col_count);
         
     | 
| 
       708 
     | 
    
         
            -
                        for (col_idx = 0; col_idx < col_count; col_idx++) {
         
     | 
| 
       709 
     | 
    
         
            -
                            vector = duckdb_data_chunk_get_vector(chunk, col_idx);
         
     | 
| 
       710 
     | 
    
         
            -
                            val = vector_value(vector, row_idx);
         
     | 
| 
       711 
     | 
    
         
            -
                            rb_ary_store(row, col_idx, val);
         
     | 
| 
       712 
     | 
    
         
            -
                        }
         
     | 
| 
       713 
     | 
    
         
            -
                        rb_yield(row);
         
     | 
| 
       714 
     | 
    
         
            -
                    }
         
     | 
| 
       715 
     | 
    
         
            -
                    duckdb_destroy_data_chunk(&chunk);
         
     | 
| 
       716 
     | 
    
         
            -
                }
         
     | 
| 
       717 
     | 
    
         
            -
                return Qnil;
         
     | 
| 
       718 
     | 
    
         
            -
            }
         
     | 
| 
       719 
     | 
    
         
            -
             
     | 
| 
       720 
     | 
    
         
            -
            void init_duckdb_result(void) {
         
     | 
| 
      
 760 
     | 
    
         
            +
            void rbduckdb_init_duckdb_result(void) {
         
     | 
| 
       721 
761 
     | 
    
         
             
                cDuckDBResult = rb_define_class_under(mDuckDB, "Result", rb_cObject);
         
     | 
| 
       722 
762 
     | 
    
         
             
                rb_define_alloc_func(cDuckDBResult, allocate);
         
     | 
| 
       723 
763 
     | 
    
         | 
| 
         @@ -725,6 +765,9 @@ void init_duckdb_result(void) { 
     | 
|
| 
       725 
765 
     | 
    
         
             
                rb_define_method(cDuckDBResult, "row_count", duckdb_result_row_count, 0);
         
     | 
| 
       726 
766 
     | 
    
         
             
                rb_define_method(cDuckDBResult, "rows_changed", duckdb_result_rows_changed, 0);
         
     | 
| 
       727 
767 
     | 
    
         
             
                rb_define_method(cDuckDBResult, "columns", duckdb_result_columns, 0);
         
     | 
| 
      
 768 
     | 
    
         
            +
                rb_define_method(cDuckDBResult, "streaming?", duckdb_result_streaming_p, 0);
         
     | 
| 
      
 769 
     | 
    
         
            +
                rb_define_method(cDuckDBResult, "chunk_each", duckdb_result_chunk_each, 0);
         
     | 
| 
      
 770 
     | 
    
         
            +
                rb_define_private_method(cDuckDBResult, "_chunk_stream", duckdb_result__chunk_stream, 0);
         
     | 
| 
       728 
771 
     | 
    
         
             
                rb_define_private_method(cDuckDBResult, "_column_type", duckdb_result__column_type, 1);
         
     | 
| 
       729 
772 
     | 
    
         
             
                rb_define_private_method(cDuckDBResult, "_null?", duckdb_result__is_null, 2);
         
     | 
| 
       730 
773 
     | 
    
         
             
                rb_define_private_method(cDuckDBResult, "_to_boolean", duckdb_result__to_boolean, 2);
         
     | 
| 
         @@ -742,5 +785,4 @@ void init_duckdb_result(void) { 
     | 
|
| 
       742 
785 
     | 
    
         
             
                rb_define_private_method(cDuckDBResult, "_enum_internal_type", duckdb_result__enum_internal_type, 1);
         
     | 
| 
       743 
786 
     | 
    
         
             
                rb_define_private_method(cDuckDBResult, "_enum_dictionary_size", duckdb_result__enum_dictionary_size, 1);
         
     | 
| 
       744 
787 
     | 
    
         
             
                rb_define_private_method(cDuckDBResult, "_enum_dictionary_value", duckdb_result__enum_dictionary_value, 2);
         
     | 
| 
       745 
     | 
    
         
            -
                rb_define_method(cDuckDBResult, "chunk_each", duckdb_result_chunk_each, 0);
         
     | 
| 
       746 
788 
     | 
    
         
             
            }
         
     | 
    
        data/ext/duckdb/result.h
    CHANGED
    
    | 
         @@ -8,8 +8,8 @@ struct _rubyDuckDBResult { 
     | 
|
| 
       8 
8 
     | 
    
         
             
            typedef struct _rubyDuckDBResult rubyDuckDBResult;
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
            rubyDuckDBResult *get_struct_result(VALUE obj);
         
     | 
| 
       11 
     | 
    
         
            -
            void  
     | 
| 
       12 
     | 
    
         
            -
            VALUE  
     | 
| 
      
 11 
     | 
    
         
            +
            void rbduckdb_init_duckdb_result(void);
         
     | 
| 
      
 12 
     | 
    
         
            +
            VALUE rbduckdb_create_result(void);
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
            #endif
         
     | 
| 
       15 
15 
     | 
    
         | 
    
        data/ext/duckdb/ruby-duckdb.h
    CHANGED
    
    
    
        data/ext/duckdb/util.c
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #include "ruby-duckdb.h"
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            duckdb_date  
     | 
| 
      
 3 
     | 
    
         
            +
            duckdb_date rbduckdb_to_duckdb_date_from_value(VALUE year, VALUE month, VALUE day) {
         
     | 
| 
       4 
4 
     | 
    
         
             
                duckdb_date_struct dt_struct;
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
                dt_struct.year = NUM2INT(year);
         
     | 
| 
         @@ -10,7 +10,7 @@ duckdb_date to_duckdb_date_from_value(VALUE year, VALUE month, VALUE day) { 
     | 
|
| 
       10 
10 
     | 
    
         
             
                return duckdb_to_date(dt_struct);
         
     | 
| 
       11 
11 
     | 
    
         
             
            }
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
            duckdb_time  
     | 
| 
      
 13 
     | 
    
         
            +
            duckdb_time rbduckdb_to_duckdb_time_from_value(VALUE hour, VALUE min, VALUE sec, VALUE micros) {
         
     | 
| 
       14 
14 
     | 
    
         
             
                duckdb_time_struct time_st;
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
                time_st.hour = NUM2INT(hour);
         
     | 
| 
         @@ -21,7 +21,7 @@ duckdb_time to_duckdb_time_from_value(VALUE hour, VALUE min, VALUE sec, VALUE mi 
     | 
|
| 
       21 
21 
     | 
    
         
             
                return duckdb_to_time(time_st);
         
     | 
| 
       22 
22 
     | 
    
         
             
            }
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
            duckdb_timestamp  
     | 
| 
      
 24 
     | 
    
         
            +
            duckdb_timestamp rbduckdb_to_duckdb_timestamp_from_value(VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros) {
         
     | 
| 
       25 
25 
     | 
    
         
             
                duckdb_timestamp_struct timestamp_st;
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                timestamp_st.date.year = NUM2INT(year);
         
     | 
| 
         @@ -35,7 +35,7 @@ duckdb_timestamp to_duckdb_timestamp_from_value(VALUE year, VALUE month, VALUE d 
     | 
|
| 
       35 
35 
     | 
    
         
             
                return duckdb_to_timestamp(timestamp_st);
         
     | 
| 
       36 
36 
     | 
    
         
             
            }
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
            void  
     | 
| 
      
 38 
     | 
    
         
            +
            void rbduckdb_to_duckdb_interval_from_value(duckdb_interval* interval, VALUE months, VALUE days, VALUE micros) {
         
     | 
| 
       39 
39 
     | 
    
         
             
                interval->months = NUM2INT(months);
         
     | 
| 
       40 
40 
     | 
    
         
             
                interval->days = NUM2INT(days);
         
     | 
| 
       41 
41 
     | 
    
         
             
                interval->micros = NUM2LL(micros);
         
     | 
    
        data/ext/duckdb/util.h
    CHANGED
    
    | 
         @@ -1,9 +1,9 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #ifndef RUBY_DUCKDB_UTIL_H
         
     | 
| 
       2 
2 
     | 
    
         
             
            #define RUBY_DUCKDB_UTIL_H
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            duckdb_date  
     | 
| 
       5 
     | 
    
         
            -
            duckdb_time  
     | 
| 
       6 
     | 
    
         
            -
            duckdb_timestamp  
     | 
| 
       7 
     | 
    
         
            -
            void  
     | 
| 
      
 4 
     | 
    
         
            +
            duckdb_date rbduckdb_to_duckdb_date_from_value(VALUE year, VALUE month, VALUE day);
         
     | 
| 
      
 5 
     | 
    
         
            +
            duckdb_time rbduckdb_to_duckdb_time_from_value(VALUE hour, VALUE min, VALUE sec, VALUE micros);
         
     | 
| 
      
 6 
     | 
    
         
            +
            duckdb_timestamp rbduckdb_to_duckdb_timestamp_from_value(VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros);
         
     | 
| 
      
 7 
     | 
    
         
            +
            void rbduckdb_to_duckdb_interval_from_value(duckdb_interval* interval, VALUE months, VALUE days, VALUE micros);
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            #endif
         
     | 
    
        data/lib/duckdb/appender.rb
    CHANGED
    
    | 
         @@ -86,16 +86,7 @@ module DuckDB 
     | 
|
| 
       86 
86 
     | 
    
         
             
                #   appender.flush
         
     | 
| 
       87 
87 
     | 
    
         
             
                #
         
     | 
| 
       88 
88 
     | 
    
         
             
                def append_time(value)
         
     | 
| 
       89 
     | 
    
         
            -
                  time =  
     | 
| 
       90 
     | 
    
         
            -
                         when Time
         
     | 
| 
       91 
     | 
    
         
            -
                           value
         
     | 
| 
       92 
     | 
    
         
            -
                         else
         
     | 
| 
       93 
     | 
    
         
            -
                           begin
         
     | 
| 
       94 
     | 
    
         
            -
                             Time.parse(value)
         
     | 
| 
       95 
     | 
    
         
            -
                           rescue
         
     | 
| 
       96 
     | 
    
         
            -
                             raise(ArgumentError, "Cannot parse argument `#{value}` to Time.")
         
     | 
| 
       97 
     | 
    
         
            -
                           end
         
     | 
| 
       98 
     | 
    
         
            -
                         end
         
     | 
| 
      
 89 
     | 
    
         
            +
                  time = _parse_time(value)
         
     | 
| 
       99 
90 
     | 
    
         | 
| 
       100 
91 
     | 
    
         
             
                  _append_time(time.hour, time.min, time.sec, time.usec)
         
     | 
| 
       101 
92 
     | 
    
         
             
                end
         
     |