iceberg 0.12.0 → 0.12.1
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/CHANGELOG.md +6 -0
- data/Cargo.lock +568 -412
- data/README.md +33 -8
- data/ext/iceberg/Cargo.toml +17 -17
- data/ext/iceberg/src/catalog.rs +10 -13
- data/ext/iceberg/src/error.rs +14 -1
- data/ext/iceberg/src/lib.rs +1 -1
- data/ext/iceberg/src/scan.rs +4 -4
- data/ext/iceberg/src/schema.rs +2 -1
- data/ext/iceberg/src/utils.rs +1 -0
- data/lib/iceberg/catalog.rb +6 -1
- data/lib/iceberg/version.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
|
@@ -31,10 +31,17 @@ catalog.create_namespace("main")
|
|
|
31
31
|
Create a table
|
|
32
32
|
|
|
33
33
|
```ruby
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
table =
|
|
35
|
+
catalog.create_table("events") do |t|
|
|
36
|
+
t.bigint "id"
|
|
37
|
+
t.float "value"
|
|
38
|
+
end
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Append data
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
table.append([{"id" => 1, "value" => 3.0}, {"id" => 2, "value" => 4.0}])
|
|
38
45
|
```
|
|
39
46
|
|
|
40
47
|
Or with [Polars](https://github.com/ankane/ruby-polars)
|
|
@@ -45,6 +52,18 @@ table = catalog.create_table("events", schema: df.schema)
|
|
|
45
52
|
table.append(df)
|
|
46
53
|
```
|
|
47
54
|
|
|
55
|
+
Or with [Nanoarrow](https://github.com/ankane/nanoarrow-ruby)
|
|
56
|
+
|
|
57
|
+
```ruby
|
|
58
|
+
arr =
|
|
59
|
+
Nanoarrow::Array.new(
|
|
60
|
+
[{"id" => 1, "value" => 3.0}, {"id" => 2, "value" => 4.0}],
|
|
61
|
+
Nanoarrow.struct({"a" => Nanoarrow.int64, "b" => Nanoarrow.string})
|
|
62
|
+
)
|
|
63
|
+
table = catalog.create_table("events", schema: arr.schema)
|
|
64
|
+
table.append(arr)
|
|
65
|
+
```
|
|
66
|
+
|
|
48
67
|
Load a table
|
|
49
68
|
|
|
50
69
|
```ruby
|
|
@@ -54,7 +73,11 @@ table = catalog.load_table("events")
|
|
|
54
73
|
Query a table
|
|
55
74
|
|
|
56
75
|
```ruby
|
|
76
|
+
table.to_a
|
|
77
|
+
# or
|
|
57
78
|
table.to_polars.collect
|
|
79
|
+
# or
|
|
80
|
+
table.scan.to_arrow
|
|
58
81
|
```
|
|
59
82
|
|
|
60
83
|
## Catalog Types
|
|
@@ -69,8 +92,6 @@ Iceberg::RestCatalog.new(
|
|
|
69
92
|
|
|
70
93
|
### S3 Tables
|
|
71
94
|
|
|
72
|
-
[unreleased]
|
|
73
|
-
|
|
74
95
|
```ruby
|
|
75
96
|
Iceberg::S3TablesCatalog.new(
|
|
76
97
|
arn: "arn:aws:s3tables:..."
|
|
@@ -79,8 +100,6 @@ Iceberg::S3TablesCatalog.new(
|
|
|
79
100
|
|
|
80
101
|
### Glue
|
|
81
102
|
|
|
82
|
-
[unreleased]
|
|
83
|
-
|
|
84
103
|
```ruby
|
|
85
104
|
Iceberg::GlueCatalog.new(
|
|
86
105
|
warehouse: "s3://my-bucket"
|
|
@@ -228,4 +247,10 @@ bundle exec rake test:rest
|
|
|
228
247
|
# SQL catalog
|
|
229
248
|
createdb iceberg_ruby_test
|
|
230
249
|
bundle exec rake test:sql
|
|
250
|
+
|
|
251
|
+
# S3 Tables catalog
|
|
252
|
+
bundle exec rake test:s3tables
|
|
253
|
+
|
|
254
|
+
# Glue catalog
|
|
255
|
+
bundle exec rake test:glue
|
|
231
256
|
```
|
data/ext/iceberg/Cargo.toml
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "iceberg-ruby"
|
|
3
|
-
version = "0.12.
|
|
3
|
+
version = "0.12.1"
|
|
4
4
|
license = "Apache-2.0"
|
|
5
5
|
authors = ["Andrew Kane <andrew@ankane.org>"]
|
|
6
6
|
edition = "2024"
|
|
7
|
-
rust-version = "1.
|
|
7
|
+
rust-version = "1.95"
|
|
8
8
|
publish = false
|
|
9
9
|
|
|
10
10
|
[lib]
|
|
@@ -12,23 +12,23 @@ name = "iceberg"
|
|
|
12
12
|
crate-type = ["cdylib"]
|
|
13
13
|
|
|
14
14
|
[dependencies]
|
|
15
|
-
arrow = "58"
|
|
16
|
-
arrow-array = { version = "58", features = ["ffi"] }
|
|
17
|
-
arrow-cast = "58"
|
|
18
|
-
arrow-schema = "58"
|
|
19
|
-
datafusion = { version = "
|
|
15
|
+
arrow = "58.4"
|
|
16
|
+
arrow-array = { version = "58.4", features = ["ffi"] }
|
|
17
|
+
arrow-cast = "58.4"
|
|
18
|
+
arrow-schema = "58.4"
|
|
19
|
+
datafusion = { version = "54", optional = true }
|
|
20
20
|
futures = "0.3"
|
|
21
|
-
iceberg = "=0.
|
|
22
|
-
iceberg-catalog-glue = { version = "=0.
|
|
23
|
-
iceberg-catalog-rest = { version = "=0.
|
|
24
|
-
iceberg-catalog-s3tables = { version = "=0.
|
|
25
|
-
iceberg-catalog-sql = { version = "=0.
|
|
26
|
-
iceberg-datafusion = { version = "=0.
|
|
27
|
-
iceberg-storage-opendal = "=0.
|
|
28
|
-
magnus = "0.
|
|
29
|
-
parquet = "58"
|
|
21
|
+
iceberg = "=0.11.0"
|
|
22
|
+
iceberg-catalog-glue = { version = "=0.11.0", optional = true }
|
|
23
|
+
iceberg-catalog-rest = { version = "=0.11.0", optional = true }
|
|
24
|
+
iceberg-catalog-s3tables = { version = "=0.11.0", optional = true }
|
|
25
|
+
iceberg-catalog-sql = { version = "=0.11.0", optional = true }
|
|
26
|
+
iceberg-datafusion = { version = "=0.11.0", optional = true }
|
|
27
|
+
iceberg-storage-opendal = "=0.11.0"
|
|
28
|
+
magnus = "0.9"
|
|
29
|
+
parquet = "58.4"
|
|
30
30
|
rb-sys = "0.9"
|
|
31
|
-
sqlx = { version = "0.8", features = ["postgres", "runtime-tokio", "sqlite"], default-features = false, optional = true }
|
|
31
|
+
sqlx = { version = "0.8", features = ["postgres", "runtime-tokio", "sqlite", "tls-rustls-aws-lc-rs"], default-features = false, optional = true }
|
|
32
32
|
tokio = { version = "1", features = ["rt-multi-thread"] }
|
|
33
33
|
uuid = { version = "1", features = ["v4"] }
|
|
34
34
|
|
data/ext/iceberg/src/catalog.rs
CHANGED
|
@@ -316,21 +316,18 @@ impl RbCatalog {
|
|
|
316
316
|
partition_spec: Option<&RbPartitionSpec>,
|
|
317
317
|
sort_order: Option<&RbSortOrder>,
|
|
318
318
|
properties: HashMap<String, String>,
|
|
319
|
+
format_version: u8,
|
|
319
320
|
) -> RbResult<RbTable> {
|
|
320
|
-
let format_version =
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
));
|
|
330
|
-
}
|
|
321
|
+
let format_version = match format_version {
|
|
322
|
+
1 => FormatVersion::V1,
|
|
323
|
+
2 => FormatVersion::V2,
|
|
324
|
+
3 => FormatVersion::V3,
|
|
325
|
+
_ => {
|
|
326
|
+
return Err(RbErr::new(
|
|
327
|
+
ruby.exception_arg_error(),
|
|
328
|
+
"Unsupported format version",
|
|
329
|
+
));
|
|
331
330
|
}
|
|
332
|
-
} else {
|
|
333
|
-
FormatVersion::V2
|
|
334
331
|
};
|
|
335
332
|
let creation = TableCreation::builder()
|
|
336
333
|
.name(name.0.name)
|
data/ext/iceberg/src/error.rs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
use std::error::Error as _;
|
|
2
|
+
|
|
1
3
|
use iceberg::{Error, ErrorKind};
|
|
2
4
|
use magnus::{Error as RbErr, RModule, Ruby, prelude::*};
|
|
3
5
|
|
|
@@ -14,7 +16,18 @@ pub fn to_rb_err(err: Error) -> RbErr {
|
|
|
14
16
|
|
|
15
17
|
// no way to get context separately
|
|
16
18
|
// https://github.com/apache/iceberg-rust/issues/1071
|
|
17
|
-
let message = err.message().to_string();
|
|
19
|
+
let mut message = err.message().to_string();
|
|
20
|
+
|
|
21
|
+
let mut source = err.source();
|
|
22
|
+
while let Some(s) = source {
|
|
23
|
+
let m = s.to_string();
|
|
24
|
+
if message.contains(&m) {
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
message.push_str(": ");
|
|
28
|
+
message.push_str(&m);
|
|
29
|
+
source = s.source();
|
|
30
|
+
}
|
|
18
31
|
|
|
19
32
|
if class_name == "Error" {
|
|
20
33
|
let s = err.to_string();
|
data/ext/iceberg/src/lib.rs
CHANGED
|
@@ -58,7 +58,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
|
|
|
58
58
|
class.define_method("update_namespace", method!(RbCatalog::update_namespace, 2))?;
|
|
59
59
|
class.define_method("drop_namespace", method!(RbCatalog::drop_namespace, 1))?;
|
|
60
60
|
class.define_method("list_tables", method!(RbCatalog::list_tables, 1))?;
|
|
61
|
-
class.define_method("create_table", method!(RbCatalog::create_table,
|
|
61
|
+
class.define_method("create_table", method!(RbCatalog::create_table, 7))?;
|
|
62
62
|
class.define_method("load_table", method!(RbCatalog::load_table, 1))?;
|
|
63
63
|
class.define_method("drop_table", method!(RbCatalog::drop_table, 1))?;
|
|
64
64
|
class.define_method("purge_table", method!(RbCatalog::purge_table, 1))?;
|
data/ext/iceberg/src/scan.rs
CHANGED
|
@@ -82,15 +82,15 @@ impl RbTableScan {
|
|
|
82
82
|
impl RbFileScanTask {
|
|
83
83
|
pub fn file(&self) -> RbDataFile {
|
|
84
84
|
RbDataFile {
|
|
85
|
-
file_path: self.scan.data_file_path.
|
|
86
|
-
record_count: self.scan.record_count,
|
|
87
|
-
file_size_in_bytes: self.scan.file_size_in_bytes,
|
|
85
|
+
file_path: self.scan.data_file_path().to_string(),
|
|
86
|
+
record_count: self.scan.record_count(),
|
|
87
|
+
file_size_in_bytes: self.scan.file_size_in_bytes(),
|
|
88
88
|
equality_ids: None,
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
pub fn delete_files(ruby: &Ruby, rb_self: &Self) -> RArray {
|
|
93
|
-
ruby.ary_from_iter(rb_self.scan.deletes.iter().map(|v| RbDataFile {
|
|
93
|
+
ruby.ary_from_iter(rb_self.scan.deletes().iter().map(|v| RbDataFile {
|
|
94
94
|
file_path: v.file_path.clone(),
|
|
95
95
|
record_count: None,
|
|
96
96
|
file_size_in_bytes: v.file_size_in_bytes,
|
data/ext/iceberg/src/schema.rs
CHANGED
|
@@ -10,7 +10,7 @@ use magnus::{
|
|
|
10
10
|
|
|
11
11
|
use crate::RbResult;
|
|
12
12
|
use crate::capsule::RbCapsule;
|
|
13
|
-
use crate::error::to_rb_err;
|
|
13
|
+
use crate::error::{to_rb_err, todo_error};
|
|
14
14
|
use crate::utils::{Wrap, default_value, rb_literal};
|
|
15
15
|
|
|
16
16
|
#[magnus::wrap(class = "Iceberg::Schema")]
|
|
@@ -252,6 +252,7 @@ impl RbNestedField {
|
|
|
252
252
|
RbNestedField::from(&ty.key_field),
|
|
253
253
|
RbNestedField::from(&ty.value_field),
|
|
254
254
|
))?,
|
|
255
|
+
Type::Variant(_) => return Err(todo_error(field_type)),
|
|
255
256
|
};
|
|
256
257
|
Ok(v)
|
|
257
258
|
}
|
data/ext/iceberg/src/utils.rs
CHANGED
|
@@ -160,6 +160,7 @@ pub fn default_value(ob: Value, field_type: &Type) -> RbResult<Option<Literal>>
|
|
|
160
160
|
Type::Struct(_) => return Err(todo_error(field_type)),
|
|
161
161
|
Type::List(_) => return Err(todo_error(field_type)),
|
|
162
162
|
Type::Map(_) => return Err(todo_error(field_type)),
|
|
163
|
+
Type::Variant(_) => return Err(todo_error(field_type)),
|
|
163
164
|
};
|
|
164
165
|
Ok(Some(lit))
|
|
165
166
|
}
|
data/lib/iceberg/catalog.rb
CHANGED
|
@@ -66,7 +66,12 @@ module Iceberg
|
|
|
66
66
|
schema = Schema.new
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
format_version = (properties["format-version"] || 2).to_i
|
|
70
|
+
if properties["format-version"] && (is_a?(MemoryCatalog) || is_a?(SqlCatalog))
|
|
71
|
+
properties = properties.except("format-version")
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
Table.new(@catalog.create_table(with_namespace(table_name), schema, location, partition_spec, sort_order, properties, format_version), @catalog)
|
|
70
75
|
end
|
|
71
76
|
|
|
72
77
|
def load_table(table_name)
|
data/lib/iceberg/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: iceberg
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.12.
|
|
4
|
+
version: 0.12.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Kane
|
|
@@ -88,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
89
|
version: '0'
|
|
90
90
|
requirements: []
|
|
91
|
-
rubygems_version: 4.0.
|
|
91
|
+
rubygems_version: 4.0.20
|
|
92
92
|
specification_version: 4
|
|
93
93
|
summary: Apache Iceberg for Ruby
|
|
94
94
|
test_files: []
|