Class: DuckDB::Result

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/duckdb/result.rb,
ext/duckdb/result.c

Overview

The Result class encapsulates a execute result of DuckDB database.

The usage is as follows:

require 'duckdb'

db = DuckDB::Database.open # database in memory
con = db.connect

con.execute('CREATE TABLE users (id INTEGER, name VARCHAR(30))')

con.execute("INSERT into users VALUES(1, 'Alice')")
con.execute("INSERT into users VALUES(2, 'Bob')")
con.execute("INSERT into users VALUES(3, 'Cathy')")

result = con.execute('SELECT * from users')
result.each do |row|
  p row
end

Constant Summary collapse

RETURN_TYPES =
%i[invalid changed_rows nothing query_result].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.newObject

Raises:



33
34
35
# File 'lib/duckdb/result.rb', line 33

def new
  raise DuckDB::Error, 'DuckDB::Result cannot be instantiated directly.'
end

Instance Method Details

#arrow_c_streamDuckDB::ArrowArrayStream

EXPERIMENTAL

Exports the result as an Arrow C stream

(Arrow C Data Interface). The returned stream object satisfies the Ruby Arrow C stream protocol, so it can be consumed directly by ruby-polars, red-arrow and other Arrow consumers:

result = con.query('SELECT * FROM users')
df = Polars::DataFrame.new(result)

The stream consumes the result’s chunks; a result can be exported only once. This API is built on DuckDB’s unstable Arrow C API and may change in any minor release.



682
683
684
685
686
687
688
689
690
691
692
693
# File 'ext/duckdb/result.c', line 682

static VALUE result_arrow_c_stream(VALUE oDuckDBResult) {
    rubyDuckDBResult *ctx;
    VALUE stream;

    TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
    if (ctx->arrow_exported) {
        rb_raise(eDuckDBError, "result is already exported as an Arrow stream");
    }
    stream = rbduckdb_create_arrow_array_stream(oDuckDBResult);
    ctx->arrow_exported = true;
    return stream;
}

#column_countInteger Also known as: column_size

Returns the column size of the result.

DuckDB::Database.open do |db|
  db.connect do |con|
    r = con.query('CREATE TABLE t2 (id INT, name VARCHAR(128))')
    r = con.query("INSERT INTO t2 VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Catherine')")
    r = con.query('SELECT id FROM t2')
    r.column_count # => 1
    r = con.query('SELECT id, name FROM t2')
    r.column_count # => 2
  end
end

Returns:

  • (Integer)


140
141
142
143
144
# File 'ext/duckdb/result.c', line 140

static VALUE result_column_count(VALUE oDuckDBResult) {
    rubyDuckDBResult *ctx;
    TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
    return LL2NUM(duckdb_column_count(&(ctx->result)));
}

#columnsDuckDB::Column[]

Returns the column class Lists.

Returns:



153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'ext/duckdb/result.c', line 153

static VALUE result_columns(VALUE oDuckDBResult) {
    rubyDuckDBResult *ctx;
    TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);

    idx_t col_idx;
    idx_t column_count = duckdb_column_count(&(ctx->result));

    VALUE ary = rb_ary_new2(column_count);
    for(col_idx = 0; col_idx < column_count; col_idx++) {
        VALUE column = rbduckdb_create_column(oDuckDBResult, col_idx);
        rb_ary_store(ary, col_idx, column);
    }
    return ary;
}

#eachObject



38
39
40
41
42
# File 'lib/duckdb/result.rb', line 38

def each(&)
  return _chunk_stream unless block_given?

  _chunk_stream(&)
end

#enum_dictionary_values(col_index) ⇒ Object

returns all available ENUM type values of the specified column index.

require 'duckdb'
db = DuckDB::Database.open('duckdb_database')
con = db.connect
con.execute("CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy', '𝘾𝝾օɭ 😎')")
con.execute("CREATE TABLE enums (id INTEGER, mood mood)")
result = con.query('SELECT * FROM enums')
result.enum_dictionary_values(1) # => ['sad', 'ok', 'happy', '𝘾𝝾օɭ 😎']

Raises:

  • (ArgumentError)


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/duckdb/result.rb', line 83

def enum_dictionary_values(col_index)
  column = columns[col_index]

  raise ArgumentError, "Invalid index: #{col_index}" if column.nil? || col_index.negative?

  lt = column.logical_type

  raise DuckDB::Error, "Column[#{col_index}] type is not enum" if lt.type != :enum

  values = []
  lt.dictionary_size.times do |i|
    values << lt.dictionary_value_at(i)
  end
  values
end

#return_typeObject

returns return type. The return value is one of the following symbols:

:invalid, :changed_rows, :nothing, :query_result

 require 'duckdb'
 db = DuckDB::Database.open('duckdb_database')
 con = db.connect
 result = con.execute('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
 result.return_type # => :nothing

Raises:



52
53
54
55
56
57
# File 'lib/duckdb/result.rb', line 52

def return_type
  i = _return_type
  raise DuckDB::Error, "Unknown return type: #{i}" if i >= RETURN_TYPES.size

  RETURN_TYPES[i]
end

#rows_changedInteger

Returns the count of rows changed.

DuckDB::Database.open do |db|
  db.connect do |con|
    r = con.query('CREATE TABLE t2 (id INT)')
    r.rows_changed # => 0
    r = con.query('INSERT INTO t2 VALUES (1), (2), (3)')
    r.rows_changed # => 3
    r = con.query('UPDATE t2 SET id = id + 1 WHERE id > 1')
    r.rows_changed # => 2
    r = con.query('DELETE FROM t2 WHERE id = 0')
    r.rows_changed # => 0
    r = con.query('DELETE FROM t2 WHERE id = 4')
    r.rows_changed # => 1
  end
end

Returns:

  • (Integer)


116
117
118
119
120
# File 'ext/duckdb/result.c', line 116

static VALUE result_rows_changed(VALUE oDuckDBResult) {
    rubyDuckDBResult *ctx;
    TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
    return LL2NUM(duckdb_rows_changed(&(ctx->result)));
}

#statement_typeObject

returns statement type. The return value is one of the following symbols:

:invalid, :select, :insert, :update, :explain, :delete, :prepare, :create,
:execute, :alter, :transaction, :copy, :analyze, :variable_set, :create_func,
:drop, :export, :pragma, :vacuum, :call, :set, :load, :relation, :extension,
:logical_plan, :attach, :detach, :multi

 require 'duckdb'
 db = DuckDB::Database.open('duckdb_database')
 con = db.connect
 result = con.execute('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
 result.statement_type # => :create


70
71
72
73
# File 'lib/duckdb/result.rb', line 70

def statement_type
  i = _statement_type
  Converter::IntToSym.statement_type_to_sym(i)
end