diff --git a/lib/types/out.zig b/lib/types/out.zig index 32069ab..97a8cef 100644 --- a/lib/types/out.zig +++ b/lib/types/out.zig @@ -29,7 +29,7 @@ pub const DataType = enum { pub fn is_array(self: DataType) bool { 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, }; } diff --git a/src/stuffs/filter.zig b/src/stuffs/filter.zig index 069b961..d83f580 100644 --- a/src/stuffs/filter.zig +++ b/src/stuffs/filter.zig @@ -16,6 +16,8 @@ const DateTime = @import("dtype").DateTime; const UUID = @import("dtype").UUID; const Data = @import("ZipponData").Data; +const log = std.log.scoped(.filter); + const ComparisonOperator = enum { equal, different, @@ -64,7 +66,7 @@ pub const ConditionValue = union(enum) { float_array: std.ArrayList(f64), bool_array: std.ArrayList(bool), 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 { switch (self) { @@ -73,9 +75,9 @@ pub const ConditionValue = union(enum) { .float_array => self.float_array.deinit(), .bool_array => self.bool_array.deinit(), .unix_array => self.unix_array.deinit(), - .link_array => { - self.link_array.deinit(); - allocator.destroy(self.link_array); + .link => { + self.link.deinit(); + allocator.destroy(self.link); }, else => {}, } @@ -142,8 +144,8 @@ pub const ConditionValue = union(enum) { return ConditionValue{ .unix_array = s2t.parseArrayDatetimeUnix(allocator, value) }; } - pub fn initLinkArray(value: *std.AutoHashMap(UUID, void)) ConditionValue { - return ConditionValue{ .link_array = value }; + pub fn initLink(value: *std.AutoHashMap(UUID, void)) ConditionValue { + return ConditionValue{ .link = value }; } }; @@ -267,9 +269,9 @@ pub const Filter = struct { fn evaluateNode(self: Filter, node: *FilterNode, row: []Data) bool { return switch (node.*) { .condition => |cond| Filter.evaluateCondition(cond, row), - .logical => |log| switch (log.operator) { - .AND => self.evaluateNode(log.left, row) and self.evaluateNode(log.right, row), - .OR => self.evaluateNode(log.left, row) or self.evaluateNode(log.right, row), + .logical => |logical| switch (logical.operator) { + .AND => self.evaluateNode(logical.left, row) and self.evaluateNode(logical.right, row), + .OR => self.evaluateNode(logical.left, row) or self.evaluateNode(logical.right, row), }, .empty => true, }; @@ -277,6 +279,7 @@ pub const Filter = struct { fn evaluateCondition(condition: Condition, row: []Data) bool { const row_value: Data = row[condition.data_index]; + log.debug("Checking condition {any}", .{condition}); return switch (condition.operation) { .equal => switch (condition.data_type) { .int => row_value.Int == condition.value.int, @@ -324,7 +327,15 @@ pub const Filter = struct { 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, {}); // 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 - 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 - try std.testing.expect(value.link_array.contains(uuid1)); - try std.testing.expect(value.link_array.contains(uuid2)); + try std.testing.expect(value.link.contains(uuid1)); + try std.testing.expect(value.link.contains(uuid2)); } diff --git a/src/ziqlParser.zig b/src/ziqlParser.zig index 8ef3883..f7e35fb 100644 --- a/src/ziqlParser.zig +++ b/src/ziqlParser.zig @@ -582,9 +582,8 @@ pub const Parser = struct { ); } } - } else { - // handle bool and bool array separately - if (condition.data_type == .bool) { + } else switch (condition.data_type) { + .bool => { if (token.tag != .bool_literal_true and token.tag != .bool_literal_false) { return printError( "Error: Expected bool", @@ -594,7 +593,8 @@ pub const Parser = struct { token.loc.end, ); } - } else if (condition.data_type == .bool_array) { + }, + .bool_array => { 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) { @@ -607,7 +607,8 @@ pub const Parser = struct { ); } } - } else if (condition.data_type == .link) { + }, + .link, .link_array => { switch (token.tag) { .l_bracket => { try self.parseAdditionalData( @@ -619,7 +620,7 @@ pub const Parser = struct { else => {}, } - additional_data.entity_count_to_find = 1; + if (condition.data_type == .link) additional_data.entity_count_to_find = 1; switch (token.tag) { .l_brace => { @@ -634,30 +635,8 @@ pub const Parser = struct { 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] - .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, - ), - } - } + }, + else => unreachable, } switch (condition.data_type) { @@ -672,7 +651,6 @@ pub const Parser = struct { .l_brace, .l_bracket => { const map = self.allocator.create(std.AutoHashMap(UUID, void)) catch return ZipponError.MemoryError; 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( struct_name, filter, @@ -680,7 +658,7 @@ pub const Parser = struct { &additional_data, ); 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( "Error: Expected filter", @@ -769,7 +747,7 @@ pub const Parser = struct { .in => switch (condition.data_type) { .link => {}, else => return printError( - "Error: Only link can be compare with in.", + "Error: Only link can be compare with in for now.", ZiQlParserError.ConditionError, self.toker.buffer, token.loc.start,