iceberg 0.11.1 → 0.12.0
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 +16 -0
- data/Cargo.lock +838 -455
- data/Cargo.toml +7 -0
- data/NOTICE.txt +2 -2
- data/README.md +32 -12
- data/ext/iceberg/Cargo.toml +17 -13
- data/ext/iceberg/src/arrow.rs +22 -7
- data/ext/iceberg/src/batch.rs +174 -0
- data/ext/iceberg/src/capsule.rs +24 -0
- data/ext/iceberg/src/catalog.rs +223 -49
- data/ext/iceberg/src/encryption.rs +32 -0
- data/ext/iceberg/src/error.rs +50 -17
- data/ext/iceberg/src/lib.rs +265 -41
- data/ext/iceberg/src/partitioning.rs +102 -0
- data/ext/iceberg/src/result.rs +201 -0
- data/ext/iceberg/src/ruby.rs +51 -0
- data/ext/iceberg/src/runtime.rs +5 -1
- data/ext/iceberg/src/scan.rs +116 -33
- data/ext/iceberg/src/schema.rs +305 -0
- data/ext/iceberg/src/snapshot.rs +85 -0
- data/ext/iceberg/src/sorting.rs +122 -0
- data/ext/iceberg/src/statistics.rs +71 -0
- data/ext/iceberg/src/table.rs +255 -263
- data/ext/iceberg/src/utils.rs +222 -164
- data/lib/iceberg/catalog.rb +54 -35
- data/lib/iceberg/glue_catalog.rb +5 -2
- data/lib/iceberg/memory_catalog.rb +5 -2
- data/lib/iceberg/rest_catalog.rb +5 -2
- data/lib/iceberg/result.rb +22 -0
- data/lib/iceberg/s3_tables_catalog.rb +5 -2
- data/lib/iceberg/sql_catalog.rb +5 -2
- data/lib/iceberg/table.rb +87 -21
- data/lib/iceberg/table_definition.rb +49 -7
- data/lib/iceberg/table_scan.rb +14 -0
- data/lib/iceberg/transforms.rb +64 -0
- data/lib/iceberg/types.rb +137 -0
- data/lib/iceberg/version.rb +1 -1
- data/lib/iceberg.rb +10 -5
- metadata +15 -3
- data/lib/iceberg/schema.rb +0 -10
data/ext/iceberg/src/table.rs
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
use std::collections::HashMap;
|
|
2
|
+
use std::sync::{Arc, RwLock};
|
|
3
|
+
|
|
4
|
+
use arrow_array::RecordBatch;
|
|
1
5
|
use arrow_array::ffi_stream::ArrowArrayStreamReader;
|
|
6
|
+
use arrow_cast::cast;
|
|
7
|
+
use arrow_schema::{ArrowError, DataType, Field, Schema};
|
|
2
8
|
use iceberg::TableIdent;
|
|
3
9
|
use iceberg::io::FileIO;
|
|
4
|
-
use iceberg::spec::FormatVersion;
|
|
10
|
+
use iceberg::spec::{FormatVersion, TableMetadata};
|
|
5
11
|
use iceberg::table::{StaticTable, Table};
|
|
6
12
|
use iceberg::transaction::{ApplyTransactionAction, Transaction};
|
|
7
13
|
use iceberg::writer::base_writer::data_file_writer::DataFileWriterBuilder;
|
|
@@ -11,29 +17,40 @@ use iceberg::writer::file_writer::location_generator::{
|
|
|
11
17
|
};
|
|
12
18
|
use iceberg::writer::file_writer::rolling_writer::RollingFileWriterBuilder;
|
|
13
19
|
use iceberg::writer::{IcebergWriter, IcebergWriterBuilder};
|
|
14
|
-
use magnus::{
|
|
20
|
+
use magnus::{RArray, Ruby};
|
|
15
21
|
use parquet::file::properties::WriterProperties;
|
|
16
|
-
use std::cell::RefCell;
|
|
17
|
-
use std::collections::HashMap;
|
|
18
|
-
use std::sync::Arc;
|
|
19
22
|
use uuid::Uuid;
|
|
20
23
|
|
|
21
24
|
use crate::RbResult;
|
|
22
|
-
use crate::arrow::RbArrowType;
|
|
23
25
|
use crate::catalog::RbCatalog;
|
|
26
|
+
use crate::encryption::RbEncryptedKey;
|
|
24
27
|
use crate::error::to_rb_err;
|
|
28
|
+
use crate::partitioning::RbPartitionSpec;
|
|
29
|
+
use crate::ruby::GvlExt;
|
|
25
30
|
use crate::runtime::runtime;
|
|
26
31
|
use crate::scan::RbTableScan;
|
|
27
|
-
use crate::
|
|
32
|
+
use crate::schema::RbSchema;
|
|
33
|
+
use crate::snapshot::{RbMetadataLogEntry, RbSnapshot, RbSnapshotLogEntry};
|
|
34
|
+
use crate::sorting::RbSortOrder;
|
|
35
|
+
use crate::statistics::{RbPartitionStatisticsFile, RbStatisticsFile};
|
|
36
|
+
use crate::utils::Wrap;
|
|
28
37
|
|
|
29
38
|
#[magnus::wrap(class = "Iceberg::RbTable")]
|
|
30
39
|
pub struct RbTable {
|
|
31
|
-
pub table:
|
|
40
|
+
pub table: RwLock<Table>,
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
impl RbTable {
|
|
44
|
+
pub fn identifier(&self) -> Vec<String> {
|
|
45
|
+
let table = self.table.read().unwrap();
|
|
46
|
+
let ident = table.identifier();
|
|
47
|
+
let mut vec = ident.namespace.clone().inner();
|
|
48
|
+
vec.push(ident.name.clone());
|
|
49
|
+
vec
|
|
50
|
+
}
|
|
51
|
+
|
|
35
52
|
pub fn scan(&self, snapshot_id: Option<i64>) -> RbResult<RbTableScan> {
|
|
36
|
-
let table = self.table.
|
|
53
|
+
let table = self.table.read().unwrap();
|
|
37
54
|
let mut builder = table.scan();
|
|
38
55
|
if let Some(si) = snapshot_id {
|
|
39
56
|
builder = builder.snapshot_id(si);
|
|
@@ -45,74 +62,98 @@ impl RbTable {
|
|
|
45
62
|
pub fn append(
|
|
46
63
|
ruby: &Ruby,
|
|
47
64
|
rb_self: &Self,
|
|
48
|
-
data:
|
|
65
|
+
data: Wrap<ArrowArrayStreamReader>,
|
|
49
66
|
catalog: &RbCatalog,
|
|
50
67
|
) -> RbResult<RbTable> {
|
|
51
|
-
let
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
68
|
+
let table = ruby
|
|
69
|
+
.detach(|| {
|
|
70
|
+
let runtime = runtime();
|
|
71
|
+
let table = rb_self.table.read().unwrap();
|
|
72
|
+
let catalog = catalog.catalog.read().unwrap();
|
|
73
|
+
|
|
74
|
+
let table_schema: Arc<arrow_schema::Schema> = Arc::new(
|
|
75
|
+
table
|
|
76
|
+
.metadata()
|
|
77
|
+
.current_schema()
|
|
78
|
+
.as_ref()
|
|
79
|
+
.try_into()
|
|
80
|
+
.unwrap(),
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
let location_generator = DefaultLocationGenerator::new(table.metadata())?;
|
|
84
|
+
let file_name_generator = DefaultFileNameGenerator::new(
|
|
85
|
+
// TODO move task id to suffix to match Python and Java
|
|
86
|
+
"0".to_string(),
|
|
87
|
+
Some(Uuid::new_v4().to_string()),
|
|
88
|
+
iceberg::spec::DataFileFormat::Parquet,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
let parquet_writer_builder = ParquetWriterBuilder::new(
|
|
92
|
+
WriterProperties::default(),
|
|
93
|
+
table.metadata().current_schema().clone(),
|
|
94
|
+
);
|
|
95
|
+
let rolling_file_writer_builder =
|
|
96
|
+
RollingFileWriterBuilder::new_with_default_file_size(
|
|
97
|
+
parquet_writer_builder,
|
|
98
|
+
table.file_io().clone(),
|
|
99
|
+
location_generator.clone(),
|
|
100
|
+
file_name_generator.clone(),
|
|
101
|
+
);
|
|
102
|
+
let data_file_writer_builder =
|
|
103
|
+
DataFileWriterBuilder::new(rolling_file_writer_builder);
|
|
104
|
+
let mut data_file_writer =
|
|
105
|
+
runtime.block_on(data_file_writer_builder.build(None))?;
|
|
106
|
+
|
|
107
|
+
for batch in data.0 {
|
|
108
|
+
let batch = cast_batch(batch.unwrap(), table_schema.clone())?;
|
|
109
|
+
runtime.block_on(data_file_writer.write(batch))?;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let data_files = runtime.block_on(data_file_writer.close())?;
|
|
113
|
+
|
|
114
|
+
let tx = Transaction::new(&table);
|
|
115
|
+
let append_action = tx.fast_append().add_data_files(data_files.clone());
|
|
116
|
+
let tx = append_action.apply(tx)?;
|
|
117
|
+
|
|
118
|
+
runtime.block_on(tx.commit(catalog.as_catalog()))
|
|
119
|
+
})
|
|
86
120
|
.map_err(to_rb_err)?;
|
|
87
121
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.map_err(|e| RbErr::new(ruby.exception_arg_error(), e.to_string()))?;
|
|
93
|
-
runtime
|
|
94
|
-
.block_on(data_file_writer.write(batch))
|
|
95
|
-
.map_err(to_rb_err)?;
|
|
96
|
-
}
|
|
122
|
+
Ok(RbTable {
|
|
123
|
+
table: table.into(),
|
|
124
|
+
})
|
|
125
|
+
}
|
|
97
126
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
.
|
|
127
|
+
pub fn metadata(&self) -> RbTableMetadata {
|
|
128
|
+
RbTableMetadata {
|
|
129
|
+
metadata: self.table.read().unwrap().metadata().clone(),
|
|
130
|
+
}
|
|
131
|
+
}
|
|
101
132
|
|
|
102
|
-
|
|
103
|
-
let
|
|
104
|
-
let
|
|
105
|
-
let
|
|
106
|
-
.block_on(
|
|
133
|
+
pub fn from_metadata_file(location: String) -> RbResult<Self> {
|
|
134
|
+
let file_io = FileIO::new_with_fs();
|
|
135
|
+
let table_ident = TableIdent::from_strs(["static-table", &location]).unwrap();
|
|
136
|
+
let static_table = runtime()
|
|
137
|
+
.block_on(StaticTable::from_metadata_file(
|
|
138
|
+
&location,
|
|
139
|
+
table_ident,
|
|
140
|
+
file_io,
|
|
141
|
+
))
|
|
107
142
|
.map_err(to_rb_err)?;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
table: table.into(),
|
|
143
|
+
Ok(Self {
|
|
144
|
+
table: static_table.into_table().into(),
|
|
111
145
|
})
|
|
112
146
|
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
#[magnus::wrap(class = "Iceberg::TableMetadata")]
|
|
150
|
+
pub struct RbTableMetadata {
|
|
151
|
+
pub metadata: TableMetadata,
|
|
152
|
+
}
|
|
113
153
|
|
|
154
|
+
impl RbTableMetadata {
|
|
114
155
|
pub fn format_version(&self) -> i32 {
|
|
115
|
-
match self.
|
|
156
|
+
match self.metadata.format_version() {
|
|
116
157
|
FormatVersion::V1 => 1,
|
|
117
158
|
FormatVersion::V2 => 2,
|
|
118
159
|
FormatVersion::V3 => 3,
|
|
@@ -120,273 +161,224 @@ impl RbTable {
|
|
|
120
161
|
}
|
|
121
162
|
|
|
122
163
|
pub fn uuid(&self) -> String {
|
|
123
|
-
self.
|
|
164
|
+
self.metadata.uuid().to_string()
|
|
124
165
|
}
|
|
125
166
|
|
|
126
167
|
pub fn location(&self) -> String {
|
|
127
|
-
self.
|
|
168
|
+
self.metadata.location().to_string()
|
|
128
169
|
}
|
|
129
170
|
|
|
130
171
|
pub fn last_sequence_number(&self) -> i64 {
|
|
131
|
-
self.
|
|
172
|
+
self.metadata.last_sequence_number()
|
|
132
173
|
}
|
|
133
174
|
|
|
134
175
|
pub fn next_sequence_number(&self) -> i64 {
|
|
135
|
-
self.
|
|
176
|
+
self.metadata.next_sequence_number()
|
|
136
177
|
}
|
|
137
178
|
|
|
138
179
|
pub fn last_column_id(&self) -> i32 {
|
|
139
|
-
self.
|
|
180
|
+
self.metadata.last_column_id()
|
|
140
181
|
}
|
|
141
182
|
|
|
142
183
|
pub fn last_partition_id(&self) -> i32 {
|
|
143
|
-
self.
|
|
184
|
+
self.metadata.last_partition_id()
|
|
144
185
|
}
|
|
145
186
|
|
|
146
187
|
pub fn last_updated_ms(&self) -> i64 {
|
|
147
|
-
self.
|
|
188
|
+
self.metadata.last_updated_ms()
|
|
148
189
|
}
|
|
149
190
|
|
|
150
|
-
pub fn schemas(ruby: &Ruby, rb_self: &Self) ->
|
|
151
|
-
|
|
152
|
-
for s in rb_self.table.borrow().metadata().schemas_iter() {
|
|
153
|
-
schemas.push(rb_schema(ruby, s)?)?;
|
|
154
|
-
}
|
|
155
|
-
Ok(schemas)
|
|
191
|
+
pub fn schemas(ruby: &Ruby, rb_self: &Self) -> RArray {
|
|
192
|
+
ruby.ary_from_iter(rb_self.metadata.schemas_iter().map(RbSchema::from))
|
|
156
193
|
}
|
|
157
194
|
|
|
158
|
-
pub fn schema_by_id(
|
|
159
|
-
|
|
160
|
-
Some(s) => Some(rb_schema(ruby, s)?),
|
|
161
|
-
None => None,
|
|
162
|
-
};
|
|
163
|
-
Ok(schema)
|
|
195
|
+
pub fn schema_by_id(&self, schema_id: i32) -> Option<RbSchema> {
|
|
196
|
+
self.metadata.schema_by_id(schema_id).map(|v| v.into())
|
|
164
197
|
}
|
|
165
198
|
|
|
166
|
-
pub fn current_schema(
|
|
167
|
-
|
|
199
|
+
pub fn current_schema(&self) -> RbSchema {
|
|
200
|
+
self.metadata.current_schema().into()
|
|
168
201
|
}
|
|
169
202
|
|
|
170
203
|
pub fn current_schema_id(&self) -> i32 {
|
|
171
|
-
self.
|
|
204
|
+
self.metadata.current_schema_id()
|
|
172
205
|
}
|
|
173
206
|
|
|
174
|
-
pub fn partition_specs(ruby: &Ruby, rb_self: &Self) ->
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
207
|
+
pub fn partition_specs(ruby: &Ruby, rb_self: &Self) -> RArray {
|
|
208
|
+
ruby.ary_from_iter(
|
|
209
|
+
rb_self
|
|
210
|
+
.metadata
|
|
211
|
+
.partition_specs_iter()
|
|
212
|
+
.map(RbPartitionSpec::from),
|
|
213
|
+
)
|
|
180
214
|
}
|
|
181
215
|
|
|
182
|
-
pub fn partition_spec_by_id(&self, partition_spec_id: i32) ->
|
|
183
|
-
|
|
184
|
-
.table
|
|
185
|
-
.borrow()
|
|
186
|
-
.metadata()
|
|
216
|
+
pub fn partition_spec_by_id(&self, partition_spec_id: i32) -> Option<RbPartitionSpec> {
|
|
217
|
+
self.metadata
|
|
187
218
|
.partition_spec_by_id(partition_spec_id)
|
|
188
|
-
|
|
189
|
-
Some(s) => Some(rb_partition_spec(s)?),
|
|
190
|
-
None => None,
|
|
191
|
-
};
|
|
192
|
-
Ok(partition_spec)
|
|
219
|
+
.map(|v| v.into())
|
|
193
220
|
}
|
|
194
221
|
|
|
195
|
-
pub fn default_partition_spec(&self) ->
|
|
196
|
-
|
|
222
|
+
pub fn default_partition_spec(&self) -> RbPartitionSpec {
|
|
223
|
+
self.metadata.default_partition_spec().into()
|
|
197
224
|
}
|
|
198
225
|
|
|
199
226
|
pub fn default_partition_spec_id(&self) -> i32 {
|
|
200
|
-
self.
|
|
227
|
+
self.metadata.default_partition_spec_id()
|
|
201
228
|
}
|
|
202
229
|
|
|
203
|
-
pub fn snapshots(ruby: &Ruby, rb_self: &Self) ->
|
|
204
|
-
|
|
205
|
-
for s in rb_self.table.borrow().metadata().snapshots() {
|
|
206
|
-
snapshots.push(rb_snapshot(ruby, s)?)?;
|
|
207
|
-
}
|
|
208
|
-
Ok(snapshots)
|
|
230
|
+
pub fn snapshots(ruby: &Ruby, rb_self: &Self) -> RArray {
|
|
231
|
+
ruby.ary_from_iter(rb_self.metadata.snapshots().map(RbSnapshot::from))
|
|
209
232
|
}
|
|
210
233
|
|
|
211
|
-
pub fn snapshot_by_id(
|
|
212
|
-
|
|
213
|
-
rb_self: &Self,
|
|
214
|
-
snapshot_id: i64,
|
|
215
|
-
) -> RbResult<Option<Value>> {
|
|
216
|
-
let snapshot = match rb_self
|
|
217
|
-
.table
|
|
218
|
-
.borrow()
|
|
219
|
-
.metadata()
|
|
220
|
-
.snapshot_by_id(snapshot_id)
|
|
221
|
-
{
|
|
222
|
-
Some(s) => Some(rb_snapshot(ruby, s)?),
|
|
223
|
-
None => None,
|
|
224
|
-
};
|
|
225
|
-
Ok(snapshot)
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
pub fn history(ruby: &Ruby, rb_self: &Self) -> RbResult<RArray> {
|
|
229
|
-
let history = ruby.ary_new();
|
|
230
|
-
for s in rb_self.table.borrow().metadata().history() {
|
|
231
|
-
let snapshot_log = ruby.hash_new();
|
|
232
|
-
snapshot_log.aset(ruby.to_symbol("snapshot_id"), s.snapshot_id)?;
|
|
233
|
-
// TODO timestamp
|
|
234
|
-
history.push(snapshot_log)?;
|
|
235
|
-
}
|
|
236
|
-
Ok(history)
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
pub fn metadata_log(ruby: &Ruby, rb_self: &Self) -> RbResult<RArray> {
|
|
240
|
-
let metadata_logs = ruby.ary_new();
|
|
241
|
-
for s in rb_self.table.borrow().metadata().metadata_log() {
|
|
242
|
-
let metadata_log = ruby.hash_new();
|
|
243
|
-
metadata_log.aset(
|
|
244
|
-
ruby.to_symbol("metadata_file"),
|
|
245
|
-
ruby.str_new(&s.metadata_file),
|
|
246
|
-
)?;
|
|
247
|
-
// TODO timestamp
|
|
248
|
-
metadata_logs.push(metadata_log)?;
|
|
249
|
-
}
|
|
250
|
-
Ok(metadata_logs)
|
|
234
|
+
pub fn snapshot_by_id(&self, snapshot_id: i64) -> Option<RbSnapshot> {
|
|
235
|
+
self.metadata.snapshot_by_id(snapshot_id).map(|v| v.into())
|
|
251
236
|
}
|
|
252
237
|
|
|
253
|
-
pub fn
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
238
|
+
pub fn history(ruby: &Ruby, rb_self: &Self) -> RArray {
|
|
239
|
+
ruby.ary_from_iter(
|
|
240
|
+
rb_self
|
|
241
|
+
.metadata
|
|
242
|
+
.history()
|
|
243
|
+
.iter()
|
|
244
|
+
.map(RbSnapshotLogEntry::from),
|
|
245
|
+
)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
pub fn metadata_log(ruby: &Ruby, rb_self: &Self) -> RArray {
|
|
249
|
+
ruby.ary_from_iter(
|
|
250
|
+
rb_self
|
|
251
|
+
.metadata
|
|
252
|
+
.metadata_log()
|
|
253
|
+
.iter()
|
|
254
|
+
.map(RbMetadataLogEntry::from),
|
|
255
|
+
)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
pub fn current_snapshot(&self) -> Option<RbSnapshot> {
|
|
259
|
+
self.metadata.current_snapshot().map(|v| v.into())
|
|
259
260
|
}
|
|
260
261
|
|
|
261
262
|
pub fn current_snapshot_id(&self) -> Option<i64> {
|
|
262
|
-
self.
|
|
263
|
+
self.metadata.current_snapshot_id()
|
|
263
264
|
}
|
|
264
265
|
|
|
265
|
-
pub fn snapshot_for_ref(
|
|
266
|
-
|
|
267
|
-
rb_self: &Self,
|
|
268
|
-
ref_name: String,
|
|
269
|
-
) -> RbResult<Option<Value>> {
|
|
270
|
-
let snapshot = match rb_self
|
|
271
|
-
.table
|
|
272
|
-
.borrow()
|
|
273
|
-
.metadata()
|
|
274
|
-
.snapshot_for_ref(&ref_name)
|
|
275
|
-
{
|
|
276
|
-
Some(s) => Some(rb_snapshot(ruby, s)?),
|
|
277
|
-
None => None,
|
|
278
|
-
};
|
|
279
|
-
Ok(snapshot)
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
pub fn sort_orders(ruby: &Ruby, rb_self: &Self) -> RbResult<RArray> {
|
|
283
|
-
let sort_orders = ruby.ary_new();
|
|
284
|
-
for s in rb_self.table.borrow().metadata().sort_orders_iter() {
|
|
285
|
-
sort_orders.push(rb_sort_order(s)?)?;
|
|
286
|
-
}
|
|
287
|
-
Ok(sort_orders)
|
|
266
|
+
pub fn snapshot_for_ref(&self, ref_name: String) -> Option<RbSnapshot> {
|
|
267
|
+
self.metadata.snapshot_for_ref(&ref_name).map(|v| v.into())
|
|
288
268
|
}
|
|
289
269
|
|
|
290
|
-
pub fn
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
270
|
+
pub fn sort_orders(ruby: &Ruby, rb_self: &Self) -> RArray {
|
|
271
|
+
ruby.ary_from_iter(rb_self.metadata.sort_orders_iter().map(RbSortOrder::from))
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
pub fn sort_order_by_id(&self, sort_order_id: i64) -> Option<RbSortOrder> {
|
|
275
|
+
self.metadata
|
|
295
276
|
.sort_order_by_id(sort_order_id)
|
|
296
|
-
|
|
297
|
-
Some(s) => Some(rb_sort_order(s)?),
|
|
298
|
-
None => None,
|
|
299
|
-
};
|
|
300
|
-
Ok(sort_order)
|
|
277
|
+
.map(|v| v.into())
|
|
301
278
|
}
|
|
302
279
|
|
|
303
|
-
pub fn default_sort_order(&self) ->
|
|
304
|
-
|
|
280
|
+
pub fn default_sort_order(&self) -> RbSortOrder {
|
|
281
|
+
self.metadata.default_sort_order().into()
|
|
305
282
|
}
|
|
306
283
|
|
|
307
284
|
pub fn default_sort_order_id(&self) -> i64 {
|
|
308
|
-
self.
|
|
285
|
+
self.metadata.default_sort_order_id()
|
|
309
286
|
}
|
|
310
287
|
|
|
311
288
|
pub fn properties(&self) -> HashMap<String, String> {
|
|
312
|
-
self.
|
|
289
|
+
self.metadata.properties().clone()
|
|
313
290
|
}
|
|
314
291
|
|
|
315
|
-
pub fn statistics(ruby: &Ruby, rb_self: &Self) ->
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
pub fn partition_statistics(ruby: &Ruby, rb_self: &Self) -> RbResult<RArray> {
|
|
324
|
-
let statistics = ruby.ary_new();
|
|
325
|
-
for s in rb_self
|
|
326
|
-
.table
|
|
327
|
-
.borrow()
|
|
328
|
-
.metadata()
|
|
329
|
-
.partition_statistics_iter()
|
|
330
|
-
{
|
|
331
|
-
statistics.push(rb_partition_statistics_file(s)?)?;
|
|
332
|
-
}
|
|
333
|
-
Ok(statistics)
|
|
292
|
+
pub fn statistics(ruby: &Ruby, rb_self: &Self) -> RArray {
|
|
293
|
+
ruby.ary_from_iter(
|
|
294
|
+
rb_self
|
|
295
|
+
.metadata
|
|
296
|
+
.statistics_iter()
|
|
297
|
+
.map(RbStatisticsFile::from),
|
|
298
|
+
)
|
|
334
299
|
}
|
|
335
300
|
|
|
336
|
-
pub fn
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
301
|
+
pub fn partition_statistics(ruby: &Ruby, rb_self: &Self) -> RArray {
|
|
302
|
+
ruby.ary_from_iter(
|
|
303
|
+
rb_self
|
|
304
|
+
.metadata
|
|
305
|
+
.partition_statistics_iter()
|
|
306
|
+
.map(RbPartitionStatisticsFile::from),
|
|
307
|
+
)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
pub fn statistics_for_snapshot(&self, snapshot_id: i64) -> Option<RbStatisticsFile> {
|
|
311
|
+
self.metadata
|
|
341
312
|
.statistics_for_snapshot(snapshot_id)
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
let statistics = match self
|
|
351
|
-
.table
|
|
352
|
-
.borrow()
|
|
353
|
-
.metadata()
|
|
313
|
+
.map(|v| v.into())
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
pub fn partition_statistics_for_snapshot(
|
|
317
|
+
&self,
|
|
318
|
+
snapshot_id: i64,
|
|
319
|
+
) -> Option<RbPartitionStatisticsFile> {
|
|
320
|
+
self.metadata
|
|
354
321
|
.partition_statistics_for_snapshot(snapshot_id)
|
|
355
|
-
|
|
356
|
-
Some(s) => Some(rb_partition_statistics_file(s)?),
|
|
357
|
-
None => None,
|
|
358
|
-
};
|
|
359
|
-
Ok(statistics)
|
|
322
|
+
.map(|v| v.into())
|
|
360
323
|
}
|
|
361
324
|
|
|
362
|
-
pub fn encryption_keys(ruby: &Ruby, rb_self: &Self) ->
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
325
|
+
pub fn encryption_keys(ruby: &Ruby, rb_self: &Self) -> RArray {
|
|
326
|
+
ruby.ary_from_iter(
|
|
327
|
+
rb_self
|
|
328
|
+
.metadata
|
|
329
|
+
.encryption_keys_iter()
|
|
330
|
+
.map(RbEncryptedKey::from),
|
|
331
|
+
)
|
|
368
332
|
}
|
|
369
333
|
|
|
370
|
-
pub fn encryption_key(&self, key_id: String) ->
|
|
371
|
-
|
|
372
|
-
Some(k) => Some(rb_encrypted_key(k)?),
|
|
373
|
-
None => None,
|
|
374
|
-
};
|
|
375
|
-
Ok(key)
|
|
334
|
+
pub fn encryption_key(&self, key_id: String) -> Option<RbEncryptedKey> {
|
|
335
|
+
self.metadata.encryption_key(&key_id).map(|v| v.into())
|
|
376
336
|
}
|
|
377
337
|
|
|
378
|
-
pub fn
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
338
|
+
pub fn next_row_id(&self) -> u64 {
|
|
339
|
+
self.metadata.next_row_id()
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
fn cast_batch(batch: RecordBatch, table_schema: Arc<Schema>) -> Result<RecordBatch, ArrowError> {
|
|
344
|
+
let mut fields = Vec::new();
|
|
345
|
+
let mut columns = Vec::new();
|
|
346
|
+
for (field, column) in batch.schema().fields.iter().zip(batch.columns()) {
|
|
347
|
+
match field.data_type() {
|
|
348
|
+
DataType::Utf8View => {
|
|
349
|
+
fields.push(Arc::new(Field::new(
|
|
350
|
+
field.name(),
|
|
351
|
+
DataType::Utf8,
|
|
352
|
+
field.is_nullable(),
|
|
353
|
+
)));
|
|
354
|
+
columns.push(cast(column, &DataType::Utf8)?);
|
|
355
|
+
}
|
|
356
|
+
DataType::BinaryView => {
|
|
357
|
+
// TODO convert to FixedSizeBinary if needed
|
|
358
|
+
fields.push(Arc::new(Field::new(
|
|
359
|
+
field.name(),
|
|
360
|
+
DataType::LargeBinary,
|
|
361
|
+
field.is_nullable(),
|
|
362
|
+
)));
|
|
363
|
+
columns.push(cast(column, &DataType::LargeBinary)?);
|
|
364
|
+
}
|
|
365
|
+
DataType::Timestamp(time_unit, Some(_)) => {
|
|
366
|
+
fields.push(Arc::new(Field::new(
|
|
367
|
+
field.name(),
|
|
368
|
+
DataType::Timestamp(*time_unit, Some("+00:00".into())),
|
|
369
|
+
field.is_nullable(),
|
|
370
|
+
)));
|
|
371
|
+
columns.push(cast(
|
|
372
|
+
column,
|
|
373
|
+
&DataType::Timestamp(*time_unit, Some("+00:00".into())),
|
|
374
|
+
)?);
|
|
375
|
+
}
|
|
376
|
+
_ => {
|
|
377
|
+
// cloning Arc is cheap
|
|
378
|
+
fields.push(field.clone());
|
|
379
|
+
columns.push(column.clone());
|
|
380
|
+
}
|
|
381
|
+
}
|
|
391
382
|
}
|
|
383
|
+
RecordBatch::try_new(Arc::new(Schema::new(fields)), columns)?.with_schema(table_schema)
|
|
392
384
|
}
|