Skip to content

Commit e35f4f1

Browse files
authored
Merge branch 'main' into combine-actions-counters
2 parents d31c1b6 + 399baf5 commit e35f4f1

15 files changed

Lines changed: 813 additions & 112 deletions

File tree

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
# delta-kernel-rs
1+
# Delta Kernel (rust)   [![build-status]][actions] [![latest-version]][crates.io] [![docs]][docs.rs] [![rustc-version-1.81+]][rustc]
2+
3+
[build-status]: https://img.shields.io/github/actions/workflow/status/delta-io/delta-kernel-rs/build.yml?branch=main
4+
[actions]: https://github.com/delta-io/delta-kernel-rs/actions/workflows/build.yml?query=branch%3Amain
5+
[latest-version]: https://img.shields.io/crates/v/delta_kernel.svg
6+
[crates.io]: https://crates.io/crates/delta\_kernel
7+
[rustc-version-1.81+]: https://img.shields.io/badge/rustc-1.81+-lightgray.svg
8+
[rustc]: https://blog.rust-lang.org/2024/09/05/Rust-1.81.0/
9+
[docs]: https://img.shields.io/docsrs/delta_kernel
10+
[docs.rs]: https://docs.rs/delta_kernel/latest/delta_kernel/
211

312
Delta-kernel-rs is an experimental [Delta][delta] implementation focused on interoperability with a
413
wide range of query engines. It currently supports reads and (experimental) writes. Only blind

ffi/examples/visit-expression/expression.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ enum LitType {
5353
Decimal,
5454
Null,
5555
Struct,
56-
Array
56+
Array,
57+
Map
5758
};
5859
enum ExpressionType { BinOp, Variadic, Literal, Unary, Column };
5960
enum VariadicType {
@@ -103,6 +104,10 @@ struct Struct {
103104
struct ArrayData {
104105
ExpressionItemList exprs;
105106
};
107+
struct MapData {
108+
ExpressionItemList keys;
109+
ExpressionItemList vals;
110+
};
106111
struct Literal {
107112
enum LitType type;
108113
union LiteralValue {
@@ -116,6 +121,7 @@ struct Literal {
116121
char* string_data;
117122
struct Struct struct_data;
118123
struct ArrayData array_data;
124+
struct MapData map_data;
119125
struct BinaryData binary;
120126
struct Decimal decimal;
121127
} value;
@@ -275,6 +281,18 @@ void visit_expr_array_literal(void* data, uintptr_t sibling_list_id, uintptr_t c
275281
put_expr_item(data, sibling_list_id, literal, Literal);
276282
}
277283

284+
void visit_expr_map_literal(void* data,
285+
uintptr_t sibling_list_id,
286+
uintptr_t key_list_id,
287+
uintptr_t value_list_id) {
288+
struct Literal* literal = malloc(sizeof(struct Literal));
289+
literal->type = Map;
290+
struct MapData* map = &(literal->value.map_data);
291+
map->keys = get_expr_list(data, key_list_id);
292+
map->vals = get_expr_list(data, value_list_id);
293+
put_expr_item(data, sibling_list_id, literal, Literal);
294+
}
295+
278296
/*************************************************************
279297
* Unary Expressions
280298
************************************************************/
@@ -339,6 +357,7 @@ ExpressionItemList construct_predicate(SharedExpression* predicate) {
339357
.visit_literal_string = visit_expr_string_literal,
340358
.visit_literal_struct = visit_expr_struct_literal,
341359
.visit_literal_array = visit_expr_array_literal,
360+
.visit_literal_map = visit_expr_map_literal,
342361
.visit_and = visit_expr_and,
343362
.visit_or = visit_expr_or,
344363
.visit_not = visit_expr_not,
@@ -394,6 +413,12 @@ void free_expression_item(ExpressionItem ref) {
394413
free_expression_list(array->exprs);
395414
break;
396415
}
416+
case Map: {
417+
struct MapData* map = &lit->value.map_data;
418+
free_expression_list(map->keys);
419+
free_expression_list(map->vals);
420+
break;
421+
}
397422
case String: {
398423
free(lit->value.string_data);
399424
break;

ffi/examples/visit-expression/expression_print.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,27 @@ void print_tree_helper(ExpressionItem ref, int depth) {
175175
struct ArrayData* array = &lit->value.array_data;
176176
print_expression_item_list(array->exprs, depth + 1);
177177
break;
178+
case Map:
179+
printf("Map\n");
180+
struct MapData* map_data = &lit->value.map_data;
181+
for (size_t i = 0; i < map_data->keys.len; i++) {
182+
print_n_spaces(depth + 1);
183+
184+
// Extract key
185+
ExpressionItem key = map_data->keys.list[i];
186+
assert(key.type == Literal);
187+
struct Literal* key_lit = key.ref;
188+
assert(key_lit->type == String);
189+
// Extract val
190+
ExpressionItem val = map_data->vals.list[i];
191+
assert(val.type == Literal);
192+
struct Literal* val_lit = val.ref;
193+
assert(val_lit->type == String);
194+
195+
// instead of recursing (which forces newlines) we just directly print strings here
196+
printf("String(%s): String(%s)\n", key_lit->value.string_data, val_lit->value.string_data);
197+
}
198+
break;
178199
}
179200
break;
180201
}

ffi/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{kernel_string_slice, ExternEngine, KernelStringSlice};
44

55
#[repr(C)]
66
#[derive(Debug)]
7+
#[non_exhaustive]
78
pub enum KernelError {
89
UnknownError, // catch-all for unrecognized kernel Error types
910
FFIError, // errors encountered in the code layer that supports FFI
@@ -54,6 +55,7 @@ pub enum KernelError {
5455
InvalidCheckpoint,
5556
LiteralExpressionTransformError,
5657
CheckpointWriteError,
58+
SchemaError,
5759
}
5860

5961
impl From<Error> for KernelError {
@@ -116,6 +118,8 @@ impl From<Error> for KernelError {
116118
Error::LiteralExpressionTransformError(_) => {
117119
KernelError::LiteralExpressionTransformError
118120
}
121+
Error::Schema(_) => KernelError::SchemaError,
122+
_ => KernelError::UnknownError,
119123
}
120124
}
121125
}

ffi/src/expressions/kernel.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::ffi::c_void;
66
use crate::{handle::Handle, kernel_string_slice, KernelStringSlice};
77
use delta_kernel::expressions::{
88
ArrayData, BinaryExpression, BinaryOperator, Expression, JunctionExpression, JunctionOperator,
9-
Scalar, StructData, UnaryExpression, UnaryOperator,
9+
MapData, Scalar, StructData, UnaryExpression, UnaryOperator,
1010
};
1111

1212
/// Free the memory the passed SharedExpression
@@ -113,6 +113,15 @@ pub struct EngineExpressionVisitor {
113113
/// The values of the array are in a list identified by `child_list_id`.
114114
pub visit_literal_array:
115115
extern "C" fn(data: *mut c_void, sibling_list_id: usize, child_list_id: usize),
116+
/// Visit a map literal belonging to the list identified by `sibling_list_id`.
117+
/// The keys of the map are in order in a list identified by `key_list_id`. The values of the
118+
/// map are in order in a list identified by `value_list_id`.
119+
pub visit_literal_map: extern "C" fn(
120+
data: *mut c_void,
121+
sibling_list_id: usize,
122+
key_list_id: usize,
123+
value_list_id: usize,
124+
),
116125
/// Visits a null value belonging to the list identified by `sibling_list_id.
117126
pub visit_literal_null: extern "C" fn(data: *mut c_void, sibling_list_id: usize),
118127
/// Visits an `and` expression belonging to the list identified by `sibling_list_id`.
@@ -228,6 +237,27 @@ fn visit_expression_array(
228237
call!(visitor, visit_literal_array, sibling_list_id, child_list_id);
229238
}
230239

240+
fn visit_expression_map(
241+
visitor: &mut EngineExpressionVisitor,
242+
map_data: &MapData,
243+
sibling_list_id: usize,
244+
) {
245+
let pairs = map_data.pairs();
246+
let key_list_id = call!(visitor, make_field_list, pairs.len());
247+
let value_list_id = call!(visitor, make_field_list, pairs.len());
248+
for (key, val) in pairs {
249+
visit_expression_scalar(visitor, key, key_list_id);
250+
visit_expression_scalar(visitor, val, value_list_id);
251+
}
252+
call!(
253+
visitor,
254+
visit_literal_map,
255+
sibling_list_id,
256+
key_list_id,
257+
value_list_id
258+
);
259+
}
260+
231261
fn visit_expression_struct_literal(
232262
visitor: &mut EngineExpressionVisitor,
233263
struct_data: &StructData,
@@ -333,6 +363,7 @@ fn visit_expression_scalar(
333363
visit_expression_struct_literal(visitor, struct_data, sibling_list_id)
334364
}
335365
Scalar::Array(array) => visit_expression_array(visitor, array, sibling_list_id),
366+
Scalar::Map(map_data) => visit_expression_map(visitor, map_data, sibling_list_id),
336367
}
337368
}
338369

ffi/src/test_ffi.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ use std::sync::Arc;
44

55
use crate::{expressions::SharedExpression, handle::Handle};
66
use delta_kernel::{
7-
expressions::{column_expr, ArrayData, BinaryOperator, Expression as Expr, Scalar, StructData},
8-
schema::{ArrayType, DataType, StructField, StructType},
7+
expressions::{
8+
column_expr, ArrayData, BinaryOperator, Expression as Expr, MapData, Scalar, StructData,
9+
},
10+
schema::{ArrayType, DataType, MapType, StructField, StructType},
911
};
1012

1113
/// Constructs a kernel expression that is passed back as a SharedExpression handle. The expected
@@ -20,7 +22,18 @@ pub unsafe extern "C" fn get_testing_kernel_expression() -> Handle<SharedExpress
2022
DataType::Primitive(delta_kernel::schema::PrimitiveType::Short),
2123
false,
2224
);
23-
let array_data = ArrayData::new(array_type.clone(), vec![Scalar::Short(5), Scalar::Short(0)]);
25+
let array_data =
26+
ArrayData::try_new(array_type.clone(), vec![Scalar::Short(5), Scalar::Short(0)]).unwrap();
27+
28+
let map_type = MapType::new(DataType::STRING, DataType::STRING, false);
29+
let map_data = MapData::try_new(
30+
map_type.clone(),
31+
[
32+
("key1".to_string(), "val1".to_string()),
33+
("key2".to_string(), "val2".to_string()),
34+
],
35+
)
36+
.unwrap();
2437

2538
let nested_fields = vec![
2639
StructField::not_null("a", DataType::INTEGER),
@@ -62,6 +75,7 @@ pub unsafe extern "C" fn get_testing_kernel_expression() -> Handle<SharedExpress
6275
Expr::null_literal(DataType::SHORT),
6376
Scalar::Struct(top_level_struct).into(),
6477
Scalar::Array(array_data).into(),
78+
Scalar::Map(map_data).into(),
6579
Expr::struct_from(vec![Expr::or_from(vec![
6680
Scalar::Integer(5).into(),
6781
Scalar::Long(20).into(),

ffi/tests/test-expression-visitor/expected.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ And
3030
Array
3131
Short(5)
3232
Short(0)
33+
Map
34+
String(key1): String(val1)
35+
String(key2): String(val2)
3336
StructExpression
3437
Or
3538
Integer(5)

0 commit comments

Comments
 (0)