IN filter working
Now if I do like GRAB User { best_friends IN {name = 'Bob'}} it should work At least now the condition value is a hashmap with key as UUID.
This commit is contained in:
parent
7b2a754d81
commit
979690fec4
@ -29,7 +29,7 @@ pub const DataType = enum {
|
|||||||
|
|
||||||
pub fn is_array(self: DataType) bool {
|
pub fn is_array(self: DataType) bool {
|
||||||
return switch (self) {
|
return switch (self) {
|
||||||
.int_array, .float_array, .str_array, .bool_array, .date_array, .time_array, .datetime_array => true,
|
.int_array, .float_array, .str_array, .bool_array, .date_array, .time_array, .datetime_array, .link_array => true,
|
||||||
else => false,
|
else => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@ const DateTime = @import("dtype").DateTime;
|
|||||||
const UUID = @import("dtype").UUID;
|
const UUID = @import("dtype").UUID;
|
||||||
const Data = @import("ZipponData").Data;
|
const Data = @import("ZipponData").Data;
|
||||||
|
|
||||||
|
const log = std.log.scoped(.filter);
|
||||||
|
|
||||||
const ComparisonOperator = enum {
|
const ComparisonOperator = enum {
|
||||||
equal,
|
equal,
|
||||||
different,
|
different,
|
||||||
@ -64,7 +66,7 @@ pub const ConditionValue = union(enum) {
|
|||||||
float_array: std.ArrayList(f64),
|
float_array: std.ArrayList(f64),
|
||||||
bool_array: std.ArrayList(bool),
|
bool_array: std.ArrayList(bool),
|
||||||
unix_array: std.ArrayList(u64),
|
unix_array: std.ArrayList(u64),
|
||||||
link_array: *std.AutoHashMap(UUID, void),
|
link: *std.AutoHashMap(UUID, void),
|
||||||
|
|
||||||
pub fn deinit(self: ConditionValue, allocator: std.mem.Allocator) void {
|
pub fn deinit(self: ConditionValue, allocator: std.mem.Allocator) void {
|
||||||
switch (self) {
|
switch (self) {
|
||||||
@ -73,9 +75,9 @@ pub const ConditionValue = union(enum) {
|
|||||||
.float_array => self.float_array.deinit(),
|
.float_array => self.float_array.deinit(),
|
||||||
.bool_array => self.bool_array.deinit(),
|
.bool_array => self.bool_array.deinit(),
|
||||||
.unix_array => self.unix_array.deinit(),
|
.unix_array => self.unix_array.deinit(),
|
||||||
.link_array => {
|
.link => {
|
||||||
self.link_array.deinit();
|
self.link.deinit();
|
||||||
allocator.destroy(self.link_array);
|
allocator.destroy(self.link);
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
@ -142,8 +144,8 @@ pub const ConditionValue = union(enum) {
|
|||||||
return ConditionValue{ .unix_array = s2t.parseArrayDatetimeUnix(allocator, value) };
|
return ConditionValue{ .unix_array = s2t.parseArrayDatetimeUnix(allocator, value) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initLinkArray(value: *std.AutoHashMap(UUID, void)) ConditionValue {
|
pub fn initLink(value: *std.AutoHashMap(UUID, void)) ConditionValue {
|
||||||
return ConditionValue{ .link_array = value };
|
return ConditionValue{ .link = value };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -267,9 +269,9 @@ pub const Filter = struct {
|
|||||||
fn evaluateNode(self: Filter, node: *FilterNode, row: []Data) bool {
|
fn evaluateNode(self: Filter, node: *FilterNode, row: []Data) bool {
|
||||||
return switch (node.*) {
|
return switch (node.*) {
|
||||||
.condition => |cond| Filter.evaluateCondition(cond, row),
|
.condition => |cond| Filter.evaluateCondition(cond, row),
|
||||||
.logical => |log| switch (log.operator) {
|
.logical => |logical| switch (logical.operator) {
|
||||||
.AND => self.evaluateNode(log.left, row) and self.evaluateNode(log.right, row),
|
.AND => self.evaluateNode(logical.left, row) and self.evaluateNode(logical.right, row),
|
||||||
.OR => self.evaluateNode(log.left, row) or self.evaluateNode(log.right, row),
|
.OR => self.evaluateNode(logical.left, row) or self.evaluateNode(logical.right, row),
|
||||||
},
|
},
|
||||||
.empty => true,
|
.empty => true,
|
||||||
};
|
};
|
||||||
@ -277,6 +279,7 @@ pub const Filter = struct {
|
|||||||
|
|
||||||
fn evaluateCondition(condition: Condition, row: []Data) bool {
|
fn evaluateCondition(condition: Condition, row: []Data) bool {
|
||||||
const row_value: Data = row[condition.data_index];
|
const row_value: Data = row[condition.data_index];
|
||||||
|
log.debug("Checking condition {any}", .{condition});
|
||||||
return switch (condition.operation) {
|
return switch (condition.operation) {
|
||||||
.equal => switch (condition.data_type) {
|
.equal => switch (condition.data_type) {
|
||||||
.int => row_value.Int == condition.value.int,
|
.int => row_value.Int == condition.value.int,
|
||||||
@ -324,7 +327,15 @@ pub const Filter = struct {
|
|||||||
else => unreachable,
|
else => unreachable,
|
||||||
},
|
},
|
||||||
|
|
||||||
else => false,
|
.in => switch (condition.data_type) {
|
||||||
|
.link => condition.value.link.contains(UUID{ .bytes = row_value.UUID }),
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
|
||||||
|
.not_in => switch (condition.data_type) {
|
||||||
|
.link => !condition.value.link.contains(UUID{ .bytes = row_value.UUID }),
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,12 +401,12 @@ test "ConditionValue: link" {
|
|||||||
try hash_map.put(uuid2, {});
|
try hash_map.put(uuid2, {});
|
||||||
|
|
||||||
// Create a ConditionValue with the link
|
// Create a ConditionValue with the link
|
||||||
var value = ConditionValue.initLinkArray(&hash_map);
|
var value = ConditionValue.initLink(&hash_map);
|
||||||
|
|
||||||
// Check that the hash map contains the correct number of UUIDs
|
// Check that the hash map contains the correct number of UUIDs
|
||||||
try std.testing.expectEqual(@as(usize, 2), value.link_array.count());
|
try std.testing.expectEqual(@as(usize, 2), value.link.count());
|
||||||
|
|
||||||
// Check that specific UUIDs are in the hash map
|
// Check that specific UUIDs are in the hash map
|
||||||
try std.testing.expect(value.link_array.contains(uuid1));
|
try std.testing.expect(value.link.contains(uuid1));
|
||||||
try std.testing.expect(value.link_array.contains(uuid2));
|
try std.testing.expect(value.link.contains(uuid2));
|
||||||
}
|
}
|
||||||
|
@ -582,9 +582,8 @@ pub const Parser = struct {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else switch (condition.data_type) {
|
||||||
// handle bool and bool array separately
|
.bool => {
|
||||||
if (condition.data_type == .bool) {
|
|
||||||
if (token.tag != .bool_literal_true and token.tag != .bool_literal_false) {
|
if (token.tag != .bool_literal_true and token.tag != .bool_literal_false) {
|
||||||
return printError(
|
return printError(
|
||||||
"Error: Expected bool",
|
"Error: Expected bool",
|
||||||
@ -594,7 +593,8 @@ pub const Parser = struct {
|
|||||||
token.loc.end,
|
token.loc.end,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (condition.data_type == .bool_array) {
|
},
|
||||||
|
.bool_array => {
|
||||||
token = self.toker.next();
|
token = self.toker.next();
|
||||||
while (token.tag != .r_bracket) : (token = self.toker.next()) {
|
while (token.tag != .r_bracket) : (token = self.toker.next()) {
|
||||||
if (token.tag != .bool_literal_true and token.tag != .bool_literal_false) {
|
if (token.tag != .bool_literal_true and token.tag != .bool_literal_false) {
|
||||||
@ -607,7 +607,8 @@ pub const Parser = struct {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (condition.data_type == .link) {
|
},
|
||||||
|
.link, .link_array => {
|
||||||
switch (token.tag) {
|
switch (token.tag) {
|
||||||
.l_bracket => {
|
.l_bracket => {
|
||||||
try self.parseAdditionalData(
|
try self.parseAdditionalData(
|
||||||
@ -619,7 +620,7 @@ pub const Parser = struct {
|
|||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
additional_data.entity_count_to_find = 1;
|
if (condition.data_type == .link) additional_data.entity_count_to_find = 1;
|
||||||
|
|
||||||
switch (token.tag) {
|
switch (token.tag) {
|
||||||
.l_brace => {
|
.l_brace => {
|
||||||
@ -634,30 +635,8 @@ pub const Parser = struct {
|
|||||||
token.loc.end,
|
token.loc.end,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
} else if (condition.data_type == .link_array) {
|
},
|
||||||
switch (token.tag) { // TODO: Also be able to do an array of UUID like [00000-00000-00000 000000-000000-0000001]
|
else => unreachable,
|
||||||
.l_bracket => {
|
|
||||||
try self.parseAdditionalData(
|
|
||||||
&additional_data,
|
|
||||||
struct_name,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (token.tag) {
|
|
||||||
.l_brace => {
|
|
||||||
filter = try self.parseFilter(struct_name, false);
|
|
||||||
},
|
|
||||||
else => return printError(
|
|
||||||
"Error: Expected new filter",
|
|
||||||
ZiQlParserError.SynthaxError,
|
|
||||||
self.toker.buffer,
|
|
||||||
token.loc.start,
|
|
||||||
token.loc.end,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (condition.data_type) {
|
switch (condition.data_type) {
|
||||||
@ -672,7 +651,6 @@ pub const Parser = struct {
|
|||||||
.l_brace, .l_bracket => {
|
.l_brace, .l_bracket => {
|
||||||
const map = self.allocator.create(std.AutoHashMap(UUID, void)) catch return ZipponError.MemoryError;
|
const map = self.allocator.create(std.AutoHashMap(UUID, void)) catch return ZipponError.MemoryError;
|
||||||
map.* = std.AutoHashMap(UUID, void).init(self.allocator);
|
map.* = std.AutoHashMap(UUID, void).init(self.allocator);
|
||||||
if (condition.data_type == .link) additional_data.entity_count_to_find = 1; // FIXME: Look like it return 2 of them, not 1
|
|
||||||
try self.file_engine.populateVoidUUIDMap(
|
try self.file_engine.populateVoidUUIDMap(
|
||||||
struct_name,
|
struct_name,
|
||||||
filter,
|
filter,
|
||||||
@ -680,7 +658,7 @@ pub const Parser = struct {
|
|||||||
&additional_data,
|
&additional_data,
|
||||||
);
|
);
|
||||||
log.debug("Found {d} entity when parsing for populateVoidUUID\n", .{map.count()});
|
log.debug("Found {d} entity when parsing for populateVoidUUID\n", .{map.count()});
|
||||||
condition.value = ConditionValue.initLinkArray(map);
|
condition.value = ConditionValue.initLink(map);
|
||||||
},
|
},
|
||||||
else => return printError(
|
else => return printError(
|
||||||
"Error: Expected filter",
|
"Error: Expected filter",
|
||||||
@ -769,7 +747,7 @@ pub const Parser = struct {
|
|||||||
.in => switch (condition.data_type) {
|
.in => switch (condition.data_type) {
|
||||||
.link => {},
|
.link => {},
|
||||||
else => return printError(
|
else => return printError(
|
||||||
"Error: Only link can be compare with in.",
|
"Error: Only link can be compare with in for now.",
|
||||||
ZiQlParserError.ConditionError,
|
ZiQlParserError.ConditionError,
|
||||||
self.toker.buffer,
|
self.toker.buffer,
|
||||||
token.loc.start,
|
token.loc.start,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user