deltalake-rb 0.1.1 → 0.1.3
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 +12 -0
- data/Cargo.lock +504 -337
- data/README.md +11 -11
- data/ext/deltalake/Cargo.toml +5 -4
- data/ext/deltalake/src/error.rs +62 -15
- data/ext/deltalake/src/features.rs +67 -0
- data/ext/deltalake/src/lib.rs +632 -61
- data/ext/deltalake/src/merge.rs +205 -0
- data/lib/deltalake/table.rb +77 -28
- data/lib/deltalake/table_alterer.rb +33 -0
- data/lib/deltalake/table_merger.rb +38 -0
- data/lib/deltalake/table_optimizer.rb +20 -4
- data/lib/deltalake/utils.rb +59 -0
- data/lib/deltalake/version.rb +1 -1
- data/lib/deltalake.rb +34 -59
- metadata +6 -2
@@ -0,0 +1,205 @@
|
|
1
|
+
use deltalake::arrow::array::RecordBatchReader;
|
2
|
+
use deltalake::arrow::datatypes::Schema as ArrowSchema;
|
3
|
+
use deltalake::arrow::ffi_stream::ArrowArrayStreamReader;
|
4
|
+
use deltalake::datafusion::catalog::TableProvider;
|
5
|
+
use deltalake::datafusion::datasource::MemTable;
|
6
|
+
use deltalake::datafusion::prelude::SessionContext;
|
7
|
+
use deltalake::logstore::LogStoreRef;
|
8
|
+
use deltalake::operations::merge::MergeBuilder;
|
9
|
+
use deltalake::table::state::DeltaTableState;
|
10
|
+
use deltalake::{DeltaResult, DeltaTable};
|
11
|
+
use std::cell::RefCell;
|
12
|
+
use std::collections::HashMap;
|
13
|
+
use std::future::IntoFuture;
|
14
|
+
use std::sync::Arc;
|
15
|
+
|
16
|
+
use crate::error::RubyError;
|
17
|
+
use crate::utils::rt;
|
18
|
+
use crate::RbResult;
|
19
|
+
use crate::{
|
20
|
+
maybe_create_commit_properties, set_writer_properties, RbCommitProperties,
|
21
|
+
RbPostCommitHookProperties, RbWriterProperties,
|
22
|
+
};
|
23
|
+
|
24
|
+
#[magnus::wrap(class = "DeltaLake::RbMergeBuilder")]
|
25
|
+
pub(crate) struct RbMergeBuilder {
|
26
|
+
_builder: RefCell<Option<MergeBuilder>>,
|
27
|
+
source_alias: Option<String>,
|
28
|
+
target_alias: Option<String>,
|
29
|
+
#[allow(dead_code)]
|
30
|
+
arrow_schema: Arc<ArrowSchema>,
|
31
|
+
}
|
32
|
+
|
33
|
+
// getters
|
34
|
+
impl RbMergeBuilder {
|
35
|
+
pub fn source_alias(&self) -> Option<String> {
|
36
|
+
self.source_alias.clone()
|
37
|
+
}
|
38
|
+
|
39
|
+
pub fn target_alias(&self) -> Option<String> {
|
40
|
+
self.target_alias.clone()
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
impl RbMergeBuilder {
|
45
|
+
pub fn new(
|
46
|
+
log_store: LogStoreRef,
|
47
|
+
snapshot: DeltaTableState,
|
48
|
+
source: ArrowArrayStreamReader,
|
49
|
+
predicate: String,
|
50
|
+
source_alias: Option<String>,
|
51
|
+
target_alias: Option<String>,
|
52
|
+
safe_cast: bool,
|
53
|
+
writer_properties: Option<RbWriterProperties>,
|
54
|
+
post_commithook_properties: Option<RbPostCommitHookProperties>,
|
55
|
+
commit_properties: Option<RbCommitProperties>,
|
56
|
+
) -> DeltaResult<Self> {
|
57
|
+
let ctx = SessionContext::new();
|
58
|
+
let schema = source.schema();
|
59
|
+
let batches = vec![source.map(|batch| batch.unwrap()).collect::<Vec<_>>()];
|
60
|
+
let table_provider: Arc<dyn TableProvider> =
|
61
|
+
Arc::new(MemTable::try_new(schema.clone(), batches).unwrap());
|
62
|
+
let source_df = ctx.read_table(table_provider).unwrap();
|
63
|
+
|
64
|
+
let mut cmd =
|
65
|
+
MergeBuilder::new(log_store, snapshot, predicate, source_df).with_safe_cast(safe_cast);
|
66
|
+
|
67
|
+
if let Some(src_alias) = &source_alias {
|
68
|
+
cmd = cmd.with_source_alias(src_alias);
|
69
|
+
}
|
70
|
+
|
71
|
+
if let Some(trgt_alias) = &target_alias {
|
72
|
+
cmd = cmd.with_target_alias(trgt_alias);
|
73
|
+
}
|
74
|
+
|
75
|
+
if let Some(writer_props) = writer_properties {
|
76
|
+
cmd = cmd.with_writer_properties(set_writer_properties(writer_props)?);
|
77
|
+
}
|
78
|
+
|
79
|
+
if let Some(commit_properties) =
|
80
|
+
maybe_create_commit_properties(commit_properties, post_commithook_properties)
|
81
|
+
{
|
82
|
+
cmd = cmd.with_commit_properties(commit_properties);
|
83
|
+
}
|
84
|
+
|
85
|
+
Ok(Self {
|
86
|
+
_builder: RefCell::new(Some(cmd)),
|
87
|
+
source_alias,
|
88
|
+
target_alias,
|
89
|
+
arrow_schema: schema,
|
90
|
+
})
|
91
|
+
}
|
92
|
+
|
93
|
+
pub fn execute(&self) -> DeltaResult<(DeltaTable, String)> {
|
94
|
+
let (table, metrics) = rt().block_on(self._builder.take().unwrap().into_future())?;
|
95
|
+
Ok((table, serde_json::to_string(&metrics).unwrap()))
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
impl RbMergeBuilder {
|
100
|
+
pub fn when_matched_update(
|
101
|
+
&self,
|
102
|
+
updates: HashMap<String, String>,
|
103
|
+
predicate: Option<String>,
|
104
|
+
) -> RbResult<()> {
|
105
|
+
let mut binding = self._builder.borrow_mut();
|
106
|
+
*binding = match binding.take() {
|
107
|
+
Some(cmd) => Some(
|
108
|
+
cmd.when_matched_update(|mut update| {
|
109
|
+
for (column, expression) in updates {
|
110
|
+
update = update.update(column, expression)
|
111
|
+
}
|
112
|
+
if let Some(predicate) = predicate {
|
113
|
+
update = update.predicate(predicate)
|
114
|
+
};
|
115
|
+
update
|
116
|
+
})
|
117
|
+
.map_err(RubyError::from)?,
|
118
|
+
),
|
119
|
+
None => unreachable!(),
|
120
|
+
};
|
121
|
+
Ok(())
|
122
|
+
}
|
123
|
+
|
124
|
+
pub fn when_matched_delete(&self, predicate: Option<String>) -> RbResult<()> {
|
125
|
+
let mut binding = self._builder.borrow_mut();
|
126
|
+
*binding = match binding.take() {
|
127
|
+
Some(cmd) => Some(
|
128
|
+
cmd.when_matched_delete(|mut delete| {
|
129
|
+
if let Some(predicate) = predicate {
|
130
|
+
delete = delete.predicate(predicate)
|
131
|
+
};
|
132
|
+
delete
|
133
|
+
})
|
134
|
+
.map_err(RubyError::from)?,
|
135
|
+
),
|
136
|
+
None => unreachable!(),
|
137
|
+
};
|
138
|
+
Ok(())
|
139
|
+
}
|
140
|
+
|
141
|
+
pub fn when_not_matched_insert(
|
142
|
+
&self,
|
143
|
+
updates: HashMap<String, String>,
|
144
|
+
predicate: Option<String>,
|
145
|
+
) -> RbResult<()> {
|
146
|
+
let mut binding = self._builder.borrow_mut();
|
147
|
+
*binding = match binding.take() {
|
148
|
+
Some(cmd) => Some(
|
149
|
+
cmd.when_not_matched_insert(|mut insert| {
|
150
|
+
for (column, expression) in updates {
|
151
|
+
insert = insert.set(column, expression)
|
152
|
+
}
|
153
|
+
if let Some(predicate) = predicate {
|
154
|
+
insert = insert.predicate(predicate)
|
155
|
+
};
|
156
|
+
insert
|
157
|
+
})
|
158
|
+
.map_err(RubyError::from)?,
|
159
|
+
),
|
160
|
+
None => unreachable!(),
|
161
|
+
};
|
162
|
+
Ok(())
|
163
|
+
}
|
164
|
+
|
165
|
+
pub fn when_not_matched_by_source_update(
|
166
|
+
&self,
|
167
|
+
updates: HashMap<String, String>,
|
168
|
+
predicate: Option<String>,
|
169
|
+
) -> RbResult<()> {
|
170
|
+
let mut binding = self._builder.borrow_mut();
|
171
|
+
*binding = match binding.take() {
|
172
|
+
Some(cmd) => Some(
|
173
|
+
cmd.when_not_matched_by_source_update(|mut update| {
|
174
|
+
for (column, expression) in updates {
|
175
|
+
update = update.update(column, expression)
|
176
|
+
}
|
177
|
+
if let Some(predicate) = predicate {
|
178
|
+
update = update.predicate(predicate)
|
179
|
+
};
|
180
|
+
update
|
181
|
+
})
|
182
|
+
.map_err(RubyError::from)?,
|
183
|
+
),
|
184
|
+
None => unreachable!(),
|
185
|
+
};
|
186
|
+
Ok(())
|
187
|
+
}
|
188
|
+
|
189
|
+
pub fn when_not_matched_by_source_delete(&self, predicate: Option<String>) -> RbResult<()> {
|
190
|
+
let mut binding = self._builder.borrow_mut();
|
191
|
+
*binding = match binding.take() {
|
192
|
+
Some(cmd) => Some(
|
193
|
+
cmd.when_not_matched_by_source_delete(|mut delete| {
|
194
|
+
if let Some(predicate) = predicate {
|
195
|
+
delete = delete.predicate(predicate)
|
196
|
+
};
|
197
|
+
delete
|
198
|
+
})
|
199
|
+
.map_err(RubyError::from)?,
|
200
|
+
),
|
201
|
+
None => unreachable!(),
|
202
|
+
};
|
203
|
+
Ok(())
|
204
|
+
}
|
205
|
+
}
|
data/lib/deltalake/table.rb
CHANGED
@@ -47,9 +47,6 @@ module DeltaLake
|
|
47
47
|
if version.is_a?(Integer)
|
48
48
|
@table.load_version(version)
|
49
49
|
elsif version.is_a?(Time)
|
50
|
-
# needed for iso8601
|
51
|
-
require "time"
|
52
|
-
|
53
50
|
@table.load_with_datetime(version.utc.iso8601(9))
|
54
51
|
elsif version.is_a?(String)
|
55
52
|
@table.load_with_datetime(version)
|
@@ -112,7 +109,9 @@ module DeltaLake
|
|
112
109
|
def vacuum(
|
113
110
|
retention_hours: nil,
|
114
111
|
dry_run: true,
|
115
|
-
enforce_retention_duration: true
|
112
|
+
enforce_retention_duration: true,
|
113
|
+
post_commithook_properties: nil,
|
114
|
+
commit_properties: nil
|
116
115
|
)
|
117
116
|
if retention_hours
|
118
117
|
if retention_hours < 0
|
@@ -123,7 +122,9 @@ module DeltaLake
|
|
123
122
|
@table.vacuum(
|
124
123
|
dry_run,
|
125
124
|
retention_hours,
|
126
|
-
enforce_retention_duration
|
125
|
+
enforce_retention_duration,
|
126
|
+
commit_properties,
|
127
|
+
post_commithook_properties
|
127
128
|
)
|
128
129
|
end
|
129
130
|
|
@@ -135,49 +136,80 @@ module DeltaLake
|
|
135
136
|
TableAlterer.new(self)
|
136
137
|
end
|
137
138
|
|
139
|
+
def merge(
|
140
|
+
source,
|
141
|
+
predicate,
|
142
|
+
source_alias: nil,
|
143
|
+
target_alias: nil,
|
144
|
+
error_on_type_mismatch: true,
|
145
|
+
writer_properties: nil,
|
146
|
+
post_commithook_properties: nil,
|
147
|
+
commit_properties: nil
|
148
|
+
)
|
149
|
+
source = Utils.convert_data(source)
|
150
|
+
|
151
|
+
rb_merge_builder =
|
152
|
+
@table.create_merge_builder(
|
153
|
+
source,
|
154
|
+
predicate,
|
155
|
+
source_alias,
|
156
|
+
target_alias,
|
157
|
+
!error_on_type_mismatch,
|
158
|
+
writer_properties,
|
159
|
+
post_commithook_properties,
|
160
|
+
commit_properties
|
161
|
+
)
|
162
|
+
TableMerger.new(rb_merge_builder, @table)
|
163
|
+
end
|
164
|
+
|
138
165
|
def restore(
|
139
166
|
target,
|
140
167
|
ignore_missing_files: false,
|
141
|
-
protocol_downgrade_allowed: false
|
168
|
+
protocol_downgrade_allowed: false,
|
169
|
+
commit_properties: nil
|
142
170
|
)
|
143
171
|
if target.is_a?(Time)
|
144
|
-
# needed for iso8601
|
145
|
-
require "time"
|
146
|
-
|
147
172
|
metrics =
|
148
173
|
@table.restore(
|
149
174
|
target.utc.iso8601(9),
|
150
175
|
ignore_missing_files,
|
151
|
-
protocol_downgrade_allowed
|
176
|
+
protocol_downgrade_allowed,
|
177
|
+
commit_properties
|
152
178
|
)
|
153
179
|
else
|
154
180
|
metrics =
|
155
181
|
@table.restore(
|
156
182
|
target,
|
157
183
|
ignore_missing_files,
|
158
|
-
protocol_downgrade_allowed
|
184
|
+
protocol_downgrade_allowed,
|
185
|
+
commit_properties
|
159
186
|
)
|
160
187
|
end
|
161
188
|
JSON.parse(metrics)
|
162
189
|
end
|
163
190
|
|
164
|
-
def to_polars(eager: true)
|
191
|
+
def to_polars(eager: true, rechunk: false, columns: nil)
|
165
192
|
require "polars-df"
|
166
193
|
|
167
194
|
sources = file_uris
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
195
|
+
if sources.empty?
|
196
|
+
lf = Polars::LazyFrame.new
|
197
|
+
else
|
198
|
+
delta_keys = [
|
199
|
+
"AWS_S3_ALLOW_UNSAFE_RENAME",
|
200
|
+
"AWS_S3_LOCKING_PROVIDER",
|
201
|
+
"CONDITIONAL_PUT",
|
202
|
+
"DELTA_DYNAMO_TABLE_NAME"
|
203
|
+
]
|
204
|
+
storage_options = @storage_options&.reject { |k, _| delta_keys.include?(k.to_s.upcase) }
|
205
|
+
lf = Polars.scan_parquet(sources, storage_options: storage_options, rechunk: rechunk)
|
206
|
+
|
207
|
+
if columns
|
208
|
+
# by_name requires polars-df > 0.15.0
|
209
|
+
lf = lf.select(Polars.cs.by_name(*columns))
|
180
210
|
end
|
211
|
+
end
|
212
|
+
|
181
213
|
eager ? lf.collect : lf
|
182
214
|
end
|
183
215
|
|
@@ -185,15 +217,32 @@ module DeltaLake
|
|
185
217
|
@table.update_incremental
|
186
218
|
end
|
187
219
|
|
188
|
-
def delete(
|
189
|
-
|
220
|
+
def delete(
|
221
|
+
predicate = nil,
|
222
|
+
writer_properties: nil,
|
223
|
+
post_commithook_properties: nil,
|
224
|
+
commit_properties: nil
|
225
|
+
)
|
226
|
+
metrics =
|
227
|
+
@table.delete(
|
228
|
+
predicate,
|
229
|
+
writer_properties,
|
230
|
+
post_commithook_properties,
|
231
|
+
commit_properties
|
232
|
+
)
|
190
233
|
JSON.parse(metrics).transform_keys(&:to_sym)
|
191
234
|
end
|
192
235
|
|
193
|
-
def repair(
|
236
|
+
def repair(
|
237
|
+
dry_run: false,
|
238
|
+
post_commithook_properties: nil,
|
239
|
+
commit_properties: nil
|
240
|
+
)
|
194
241
|
metrics =
|
195
242
|
@table.repair(
|
196
|
-
dry_run
|
243
|
+
dry_run,
|
244
|
+
commit_properties,
|
245
|
+
post_commithook_properties
|
197
246
|
)
|
198
247
|
JSON.parse(metrics).transform_keys(&:to_sym)
|
199
248
|
end
|
@@ -4,6 +4,29 @@ module DeltaLake
|
|
4
4
|
@table = table
|
5
5
|
end
|
6
6
|
|
7
|
+
def add_feature(
|
8
|
+
feature,
|
9
|
+
allow_protocol_versions_increase: false
|
10
|
+
)
|
11
|
+
if !feature.is_a?(Array)
|
12
|
+
feature = [feature]
|
13
|
+
end
|
14
|
+
@table._table.add_feature(
|
15
|
+
feature,
|
16
|
+
allow_protocol_versions_increase
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_columns(fields)
|
21
|
+
if fields.is_a?(DeltaLake::Field)
|
22
|
+
fields = [fields]
|
23
|
+
end
|
24
|
+
|
25
|
+
@table._table.add_columns(
|
26
|
+
fields
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
7
30
|
def add_constraint(constraints)
|
8
31
|
if constraints.length > 1
|
9
32
|
raise ArgumentError,
|
@@ -21,5 +44,15 @@ module DeltaLake
|
|
21
44
|
raise_if_not_exists
|
22
45
|
)
|
23
46
|
end
|
47
|
+
|
48
|
+
def set_table_properties(
|
49
|
+
properties,
|
50
|
+
raise_if_not_exists: true
|
51
|
+
)
|
52
|
+
@table._table.set_table_properties(
|
53
|
+
properties,
|
54
|
+
raise_if_not_exists
|
55
|
+
)
|
56
|
+
end
|
24
57
|
end
|
25
58
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module DeltaLake
|
2
|
+
class TableMerger
|
3
|
+
def initialize(builder, table)
|
4
|
+
@builder = builder
|
5
|
+
@table = table
|
6
|
+
end
|
7
|
+
|
8
|
+
def when_matched_update(updates, predicate: nil)
|
9
|
+
@builder.when_matched_update(updates, predicate)
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def when_not_matched_insert(updates, predicate: nil)
|
14
|
+
@builder.when_not_matched_insert(updates, predicate)
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def when_matched_delete(predicate: nil)
|
19
|
+
@builder.when_matched_delete(predicate)
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def when_not_matched_by_source_update(updates, predicate: nil)
|
24
|
+
@builder.when_not_matched_by_source_update(updates, predicate)
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def when_not_matched_by_source_delete(predicate: nil)
|
29
|
+
@builder.when_not_matched_by_source_delete(predicate)
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute
|
34
|
+
metrics = @table.merge_execute(@builder)
|
35
|
+
JSON.parse(metrics).transform_keys(&:to_sym)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -5,15 +5,23 @@ module DeltaLake
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def compact(
|
8
|
+
partition_filters: nil,
|
8
9
|
target_size: nil,
|
9
10
|
max_concurrent_tasks: nil,
|
10
|
-
min_commit_interval: nil
|
11
|
+
min_commit_interval: nil,
|
12
|
+
writer_properties: nil,
|
13
|
+
post_commithook_properties: nil,
|
14
|
+
commit_properties: nil
|
11
15
|
)
|
12
16
|
metrics =
|
13
17
|
@table._table.compact_optimize(
|
18
|
+
@table._stringify_partition_values(partition_filters),
|
14
19
|
target_size,
|
15
20
|
max_concurrent_tasks,
|
16
|
-
min_commit_interval
|
21
|
+
min_commit_interval,
|
22
|
+
writer_properties,
|
23
|
+
post_commithook_properties,
|
24
|
+
commit_properties
|
17
25
|
)
|
18
26
|
@table.update_incremental
|
19
27
|
result = JSON.parse(metrics)
|
@@ -26,18 +34,26 @@ module DeltaLake
|
|
26
34
|
|
27
35
|
def z_order(
|
28
36
|
columns,
|
37
|
+
partition_filters: nil,
|
29
38
|
target_size: nil,
|
30
39
|
max_concurrent_tasks: nil,
|
31
40
|
max_spill_size: 20 * 1024 * 1024 * 1024,
|
32
|
-
min_commit_interval: nil
|
41
|
+
min_commit_interval: nil,
|
42
|
+
writer_properties: nil,
|
43
|
+
post_commithook_properties: nil,
|
44
|
+
commit_properties: nil
|
33
45
|
)
|
34
46
|
metrics =
|
35
47
|
@table._table.z_order_optimize(
|
36
48
|
Array(columns),
|
49
|
+
@table._stringify_partition_values(partition_filters),
|
37
50
|
target_size,
|
38
51
|
max_concurrent_tasks,
|
39
52
|
max_spill_size,
|
40
|
-
min_commit_interval
|
53
|
+
min_commit_interval,
|
54
|
+
writer_properties,
|
55
|
+
post_commithook_properties,
|
56
|
+
commit_properties
|
41
57
|
)
|
42
58
|
@table.update_incremental
|
43
59
|
result = JSON.parse(metrics)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module DeltaLake
|
2
|
+
module Utils
|
3
|
+
def self.convert_data(data)
|
4
|
+
if data.respond_to?(:arrow_c_stream)
|
5
|
+
# TODO convert other object types
|
6
|
+
# should probably move logic to Rust
|
7
|
+
if defined?(Polars::DataFrame) && data.is_a?(Polars::DataFrame)
|
8
|
+
data = convert_polars_data(data)
|
9
|
+
end
|
10
|
+
|
11
|
+
data.arrow_c_stream
|
12
|
+
else
|
13
|
+
raise TypeError, "Only objects implementing the Arrow C stream interface are valid inputs for source."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# unsigned integers are not part of the protocol
|
18
|
+
# https://github.com/delta-io/delta/blob/master/PROTOCOL.md#primitive-types
|
19
|
+
def self.convert_polars_data(data)
|
20
|
+
new_schema = {}
|
21
|
+
data.schema.each do |k, v|
|
22
|
+
new_type = convert_polars_type(v)
|
23
|
+
new_schema[k] = new_type if new_type
|
24
|
+
end
|
25
|
+
|
26
|
+
if new_schema.any?
|
27
|
+
data.cast(new_schema)
|
28
|
+
else
|
29
|
+
data
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.convert_polars_type(t)
|
34
|
+
case t
|
35
|
+
when Polars::UInt8
|
36
|
+
Polars::Int8
|
37
|
+
when Polars::UInt16
|
38
|
+
Polars::Int16
|
39
|
+
when Polars::UInt32
|
40
|
+
Polars::Int32
|
41
|
+
when Polars::UInt64
|
42
|
+
Polars::Int64
|
43
|
+
when Polars::Datetime
|
44
|
+
Polars::Datetime.new("us", t.time_zone) if t.time_unit != "us"
|
45
|
+
when Polars::List
|
46
|
+
inner = convert_polars_type(t.inner)
|
47
|
+
Polars::List.new(inner) if inner
|
48
|
+
when Polars::Array
|
49
|
+
inner = convert_polars_type(t.inner)
|
50
|
+
Polars::Array.new(t.inner, t.width) if inner
|
51
|
+
when Polars::Struct
|
52
|
+
if t.fields.any? { |f| convert_polars_type(f.dtype) }
|
53
|
+
fields = t.fields.map { |f| Polars::Field.new(f.name, convert_polars_type(f.dtype) || f.dtype) }
|
54
|
+
Polars::Struct.new(fields)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/deltalake/version.rb
CHANGED