diff options
| -rw-r--r-- | helpers.zig | 20 | ||||
| -rw-r--r-- | query.zig | 4 | ||||
| -rw-r--r-- | sqlite.zig | 120 | ||||
| -rw-r--r-- | vtab.zig | 22 |
4 files changed, 83 insertions, 83 deletions
diff --git a/helpers.zig b/helpers.zig index b9a6131..dd7fd4f 100644 --- a/helpers.zig +++ b/helpers.zig | |||
| @@ -16,20 +16,20 @@ pub fn setResult(ctx: ?*c.sqlite3_context, result: anytype) void { | |||
| 16 | Text => c.sqlite3_result_text(ctx, result.data.ptr, @intCast(result.data.len), c.sqliteTransientAsDestructor()), | 16 | Text => c.sqlite3_result_text(ctx, result.data.ptr, @intCast(result.data.len), c.sqliteTransientAsDestructor()), |
| 17 | Blob => c.sqlite3_result_blob(ctx, result.data.ptr, @intCast(result.data.len), c.sqliteTransientAsDestructor()), | 17 | Blob => c.sqlite3_result_blob(ctx, result.data.ptr, @intCast(result.data.len), c.sqliteTransientAsDestructor()), |
| 18 | else => switch (@typeInfo(ResultType)) { | 18 | else => switch (@typeInfo(ResultType)) { |
| 19 | .Int => |info| if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 32) { | 19 | .int => |info| if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 32) { |
| 20 | c.sqlite3_result_int(ctx, result); | 20 | c.sqlite3_result_int(ctx, result); |
| 21 | } else if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 64) { | 21 | } else if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 64) { |
| 22 | c.sqlite3_result_int64(ctx, result); | 22 | c.sqlite3_result_int64(ctx, result); |
| 23 | } else { | 23 | } else { |
| 24 | @compileError("integer " ++ @typeName(ResultType) ++ " is not representable in sqlite"); | 24 | @compileError("integer " ++ @typeName(ResultType) ++ " is not representable in sqlite"); |
| 25 | }, | 25 | }, |
| 26 | .Float => c.sqlite3_result_double(ctx, result), | 26 | .float => c.sqlite3_result_double(ctx, result), |
| 27 | .Bool => c.sqlite3_result_int(ctx, if (result) 1 else 0), | 27 | .bool => c.sqlite3_result_int(ctx, if (result) 1 else 0), |
| 28 | .Array => |arr| switch (arr.child) { | 28 | .array => |arr| switch (arr.child) { |
| 29 | u8 => c.sqlite3_result_blob(ctx, &result, arr.len, c.sqliteTransientAsDestructor()), | 29 | u8 => c.sqlite3_result_blob(ctx, &result, arr.len, c.sqliteTransientAsDestructor()), |
| 30 | else => @compileError("cannot use a result of type " ++ @typeName(ResultType)), | 30 | else => @compileError("cannot use a result of type " ++ @typeName(ResultType)), |
| 31 | }, | 31 | }, |
| 32 | .Pointer => |ptr| switch (ptr.size) { | 32 | .pointer => |ptr| switch (ptr.size) { |
| 33 | .Slice => switch (ptr.child) { | 33 | .Slice => switch (ptr.child) { |
| 34 | u8 => c.sqlite3_result_text(ctx, result.ptr, @intCast(result.len), c.sqliteTransientAsDestructor()), | 34 | u8 => c.sqlite3_result_text(ctx, result.ptr, @intCast(result.len), c.sqliteTransientAsDestructor()), |
| 35 | else => @compileError("cannot use a result of type " ++ @typeName(ResultType)), | 35 | else => @compileError("cannot use a result of type " ++ @typeName(ResultType)), |
| @@ -49,7 +49,7 @@ pub fn setTypeFromValue(comptime ArgType: type, arg: *ArgType, sqlite_value: *c. | |||
| 49 | Text => arg.*.data = sliceFromValue(sqlite_value), | 49 | Text => arg.*.data = sliceFromValue(sqlite_value), |
| 50 | Blob => arg.*.data = sliceFromValue(sqlite_value), | 50 | Blob => arg.*.data = sliceFromValue(sqlite_value), |
| 51 | else => switch (@typeInfo(ArgType)) { | 51 | else => switch (@typeInfo(ArgType)) { |
| 52 | .Int => |info| if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 32) { | 52 | .int => |info| if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 32) { |
| 53 | const value = c.sqlite3_value_int(sqlite_value); | 53 | const value = c.sqlite3_value_int(sqlite_value); |
| 54 | arg.* = @intCast(value); | 54 | arg.* = @intCast(value); |
| 55 | } else if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 64) { | 55 | } else if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 64) { |
| @@ -58,15 +58,15 @@ pub fn setTypeFromValue(comptime ArgType: type, arg: *ArgType, sqlite_value: *c. | |||
| 58 | } else { | 58 | } else { |
| 59 | @compileError("integer " ++ @typeName(ArgType) ++ " is not representable in sqlite"); | 59 | @compileError("integer " ++ @typeName(ArgType) ++ " is not representable in sqlite"); |
| 60 | }, | 60 | }, |
| 61 | .Float => { | 61 | .float => { |
| 62 | const value = c.sqlite3_value_double(sqlite_value); | 62 | const value = c.sqlite3_value_double(sqlite_value); |
| 63 | arg.* = @floatCast(value); | 63 | arg.* = @floatCast(value); |
| 64 | }, | 64 | }, |
| 65 | .Bool => { | 65 | .bool => { |
| 66 | const value = c.sqlite3_value_int(sqlite_value); | 66 | const value = c.sqlite3_value_int(sqlite_value); |
| 67 | arg.* = value > 0; | 67 | arg.* = value > 0; |
| 68 | }, | 68 | }, |
| 69 | .Pointer => |ptr| switch (ptr.size) { | 69 | .pointer => |ptr| switch (ptr.size) { |
| 70 | .Slice => switch (ptr.child) { | 70 | .Slice => switch (ptr.child) { |
| 71 | u8 => arg.* = sliceFromValue(sqlite_value), | 71 | u8 => arg.* = sliceFromValue(sqlite_value), |
| 72 | else => @compileError("cannot use an argument of type " ++ @typeName(ArgType)), | 72 | else => @compileError("cannot use an argument of type " ++ @typeName(ArgType)), |
| @@ -98,7 +98,7 @@ pub fn hasFn(comptime T: type, comptime name: []const u8) bool { | |||
| 98 | const decl_type_info = @typeInfo(decl_type); | 98 | const decl_type_info = @typeInfo(decl_type); |
| 99 | 99 | ||
| 100 | return switch (decl_type_info) { | 100 | return switch (decl_type_info) { |
| 101 | .Fn => true, | 101 | .@"fn" => true, |
| 102 | else => false, | 102 | else => false, |
| 103 | }; | 103 | }; |
| 104 | } | 104 | } |
| @@ -146,7 +146,7 @@ pub fn ParsedQuery(comptime tmp_query: []const u8) type { | |||
| 146 | const typ = if (type_info_string[0] == '?') blk: { | 146 | const typ = if (type_info_string[0] == '?') blk: { |
| 147 | const child_type = ParseType(type_info_string[1..]); | 147 | const child_type = ParseType(type_info_string[1..]); |
| 148 | break :blk @Type(std.builtin.Type{ | 148 | break :blk @Type(std.builtin.Type{ |
| 149 | .Optional = .{ | 149 | .optional = .{ |
| 150 | .child = child_type, | 150 | .child = child_type, |
| 151 | }, | 151 | }, |
| 152 | }); | 152 | }); |
| @@ -205,7 +205,7 @@ fn ParseType(comptime type_info: []const u8) type { | |||
| 205 | 205 | ||
| 206 | if (type_info[0] == 'u' or type_info[0] == 'i') { | 206 | if (type_info[0] == 'u' or type_info[0] == 'i') { |
| 207 | return @Type(std.builtin.Type{ | 207 | return @Type(std.builtin.Type{ |
| 208 | .Int = std.builtin.Type.Int{ | 208 | .int = std.builtin.Type.Int{ |
| 209 | .signedness = if (type_info[0] == 'i') .signed else .unsigned, | 209 | .signedness = if (type_info[0] == 'i') .signed else .unsigned, |
| 210 | .bits = std.fmt.parseInt(usize, type_info[1..type_info.len], 10) catch { | 210 | .bits = std.fmt.parseInt(usize, type_info[1..type_info.len], 10) catch { |
| 211 | @compileError("invalid type info " ++ type_info); | 211 | @compileError("invalid type info " ++ type_info); |
| @@ -33,7 +33,7 @@ const logger = std.log.scoped(.sqlite); | |||
| 33 | // Returns true if the passed type is a struct. | 33 | // Returns true if the passed type is a struct. |
| 34 | fn isStruct(comptime T: type) bool { | 34 | fn isStruct(comptime T: type) bool { |
| 35 | const type_info = @typeInfo(T); | 35 | const type_info = @typeInfo(T); |
| 36 | return type_info == .Struct; | 36 | return type_info == .@"struct"; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | // Returns true if the passed type will coerce to []const u8. | 39 | // Returns true if the passed type will coerce to []const u8. |
| @@ -43,9 +43,9 @@ fn isZigString(comptime T: type) bool { | |||
| 43 | return comptime blk: { | 43 | return comptime blk: { |
| 44 | // Only pointer types can be strings, no optionals | 44 | // Only pointer types can be strings, no optionals |
| 45 | const info = @typeInfo(T); | 45 | const info = @typeInfo(T); |
| 46 | if (info != .Pointer) break :blk false; | 46 | if (info != .pointer) break :blk false; |
| 47 | 47 | ||
| 48 | const ptr = &info.Pointer; | 48 | const ptr = &info.pointer; |
| 49 | // Check for CV qualifiers that would prevent coerction to []const u8 | 49 | // Check for CV qualifiers that would prevent coerction to []const u8 |
| 50 | if (ptr.is_volatile or ptr.is_allowzero) break :blk false; | 50 | if (ptr.is_volatile or ptr.is_allowzero) break :blk false; |
| 51 | 51 | ||
| @@ -57,8 +57,8 @@ fn isZigString(comptime T: type) bool { | |||
| 57 | // Otherwise check if it's an array type that coerces to slice. | 57 | // Otherwise check if it's an array type that coerces to slice. |
| 58 | if (ptr.size == .One) { | 58 | if (ptr.size == .One) { |
| 59 | const child = @typeInfo(ptr.child); | 59 | const child = @typeInfo(ptr.child); |
| 60 | if (child == .Array) { | 60 | if (child == .array) { |
| 61 | const arr = &child.Array; | 61 | const arr = &child.array; |
| 62 | break :blk arr.child == u8; | 62 | break :blk arr.child == u8; |
| 63 | } | 63 | } |
| 64 | } | 64 | } |
| @@ -668,14 +668,14 @@ pub const Db = struct { | |||
| 668 | // Validate the functions | 668 | // Validate the functions |
| 669 | 669 | ||
| 670 | const step_fn_info = switch (@typeInfo(@TypeOf(step_func))) { | 670 | const step_fn_info = switch (@typeInfo(@TypeOf(step_func))) { |
| 671 | .Fn => |fn_info| fn_info, | 671 | .@"fn" => |fn_info| fn_info, |
| 672 | else => @compileError("cannot use func, expecting a function"), | 672 | else => @compileError("cannot use func, expecting a function"), |
| 673 | }; | 673 | }; |
| 674 | if (step_fn_info.is_generic) @compileError("step function can't be generic"); | 674 | if (step_fn_info.is_generic) @compileError("step function can't be generic"); |
| 675 | if (step_fn_info.is_var_args) @compileError("step function can't be variadic"); | 675 | if (step_fn_info.is_var_args) @compileError("step function can't be variadic"); |
| 676 | 676 | ||
| 677 | const finalize_fn_info = switch (@typeInfo(@TypeOf(finalize_func))) { | 677 | const finalize_fn_info = switch (@typeInfo(@TypeOf(finalize_func))) { |
| 678 | .Fn => |fn_info| fn_info, | 678 | .@"fn" => |fn_info| fn_info, |
| 679 | else => @compileError("cannot use func, expecting a function"), | 679 | else => @compileError("cannot use func, expecting a function"), |
| 680 | }; | 680 | }; |
| 681 | if (finalize_fn_info.params.len != 1) @compileError("finalize function must take exactly one argument"); | 681 | if (finalize_fn_info.params.len != 1) @compileError("finalize function must take exactly one argument"); |
| @@ -761,7 +761,7 @@ pub const Db = struct { | |||
| 761 | const Type = @TypeOf(func); | 761 | const Type = @TypeOf(func); |
| 762 | 762 | ||
| 763 | const fn_info = switch (@typeInfo(Type)) { | 763 | const fn_info = switch (@typeInfo(Type)) { |
| 764 | .Fn => |fn_info| fn_info, | 764 | .@"fn" => |fn_info| fn_info, |
| 765 | else => @compileError("expecting a function"), | 765 | else => @compileError("expecting a function"), |
| 766 | }; | 766 | }; |
| 767 | if (fn_info.is_generic) @compileError("function can't be generic"); | 767 | if (fn_info.is_generic) @compileError("function can't be generic"); |
| @@ -893,14 +893,14 @@ pub const FunctionContext = struct { | |||
| 893 | 893 | ||
| 894 | fn splitPtrTypes(comptime Type: type) SplitPtrTypes { | 894 | fn splitPtrTypes(comptime Type: type) SplitPtrTypes { |
| 895 | switch (@typeInfo(Type)) { | 895 | switch (@typeInfo(Type)) { |
| 896 | .Pointer => |ptr_info| switch (ptr_info.size) { | 896 | .pointer => |ptr_info| switch (ptr_info.size) { |
| 897 | .One => return SplitPtrTypes{ | 897 | .One => return SplitPtrTypes{ |
| 898 | .ValueType = ptr_info.child, | 898 | .ValueType = ptr_info.child, |
| 899 | .PointerType = Type, | 899 | .PointerType = Type, |
| 900 | }, | 900 | }, |
| 901 | else => @compileError("cannot use type " ++ @typeName(Type) ++ ", must be a single-item pointer"), | 901 | else => @compileError("cannot use type " ++ @typeName(Type) ++ ", must be a single-item pointer"), |
| 902 | }, | 902 | }, |
| 903 | .Void => return SplitPtrTypes{ | 903 | .void => return SplitPtrTypes{ |
| 904 | .ValueType = void, | 904 | .ValueType = void, |
| 905 | .PointerType = undefined, | 905 | .PointerType = undefined, |
| 906 | }, | 906 | }, |
| @@ -1087,41 +1087,41 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1087 | const columns = c.sqlite3_column_count(self.stmt); | 1087 | const columns = c.sqlite3_column_count(self.stmt); |
| 1088 | 1088 | ||
| 1089 | switch (TypeInfo) { | 1089 | switch (TypeInfo) { |
| 1090 | .Int => { | 1090 | .int => { |
| 1091 | debug.assert(columns == 1); | 1091 | debug.assert(columns == 1); |
| 1092 | return try self.readInt(Type, 0); | 1092 | return try self.readInt(Type, 0); |
| 1093 | }, | 1093 | }, |
| 1094 | .Float => { | 1094 | .float => { |
| 1095 | debug.assert(columns == 1); | 1095 | debug.assert(columns == 1); |
| 1096 | return try self.readFloat(Type, 0); | 1096 | return try self.readFloat(Type, 0); |
| 1097 | }, | 1097 | }, |
| 1098 | .Bool => { | 1098 | .bool => { |
| 1099 | debug.assert(columns == 1); | 1099 | debug.assert(columns == 1); |
| 1100 | return try self.readBool(0); | 1100 | return try self.readBool(0); |
| 1101 | }, | 1101 | }, |
| 1102 | .Void => { | 1102 | .void => { |
| 1103 | debug.assert(columns == 1); | 1103 | debug.assert(columns == 1); |
| 1104 | }, | 1104 | }, |
| 1105 | .Array => { | 1105 | .array => { |
| 1106 | debug.assert(columns == 1); | 1106 | debug.assert(columns == 1); |
| 1107 | return try self.readArray(Type, 0); | 1107 | return try self.readArray(Type, 0); |
| 1108 | }, | 1108 | }, |
| 1109 | .Enum => |TI| { | 1109 | .@"enum" => |TI| { |
| 1110 | debug.assert(columns == 1); | 1110 | debug.assert(columns == 1); |
| 1111 | 1111 | ||
| 1112 | if (comptime isZigString(Type.BaseType)) { | 1112 | if (comptime isZigString(Type.BaseType)) { |
| 1113 | @compileError("cannot read into type " ++ @typeName(Type) ++ " ; BaseType " ++ @typeName(Type.BaseType) ++ " requires allocation, use nextAlloc or oneAlloc"); | 1113 | @compileError("cannot read into type " ++ @typeName(Type) ++ " ; BaseType " ++ @typeName(Type.BaseType) ++ " requires allocation, use nextAlloc or oneAlloc"); |
| 1114 | } | 1114 | } |
| 1115 | 1115 | ||
| 1116 | if (@typeInfo(Type.BaseType) == .Int) { | 1116 | if (@typeInfo(Type.BaseType) == .int) { |
| 1117 | const inner_value = try self.readField(Type.BaseType, options, 0); | 1117 | const inner_value = try self.readField(Type.BaseType, options, 0); |
| 1118 | return @enumFromInt(@as(TI.tag_type, @intCast(inner_value))); | 1118 | return @enumFromInt(@as(TI.tag_type, @intCast(inner_value))); |
| 1119 | } | 1119 | } |
| 1120 | 1120 | ||
| 1121 | @compileError("enum column " ++ @typeName(Type) ++ " must have a BaseType of either string or int"); | 1121 | @compileError("enum column " ++ @typeName(Type) ++ " must have a BaseType of either string or int"); |
| 1122 | }, | 1122 | }, |
| 1123 | .Struct => { | 1123 | .@"struct" => { |
| 1124 | std.debug.assert(columns == TypeInfo.Struct.fields.len); | 1124 | std.debug.assert(columns == TypeInfo.@"struct".fields.len); |
| 1125 | return try self.readStruct(options); | 1125 | return try self.readStruct(options); |
| 1126 | }, | 1126 | }, |
| 1127 | else => @compileError("cannot read into type " ++ @typeName(Type) ++ " ; if dynamic memory allocation is required use nextAlloc or oneAlloc"), | 1127 | else => @compileError("cannot read into type " ++ @typeName(Type) ++ " ; if dynamic memory allocation is required use nextAlloc or oneAlloc"), |
| @@ -1161,32 +1161,32 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1161 | } | 1161 | } |
| 1162 | 1162 | ||
| 1163 | switch (TypeInfo) { | 1163 | switch (TypeInfo) { |
| 1164 | .Int => { | 1164 | .int => { |
| 1165 | debug.assert(columns == 1); | 1165 | debug.assert(columns == 1); |
| 1166 | return try self.readInt(Type, 0); | 1166 | return try self.readInt(Type, 0); |
| 1167 | }, | 1167 | }, |
| 1168 | .Float => { | 1168 | .float => { |
| 1169 | debug.assert(columns == 1); | 1169 | debug.assert(columns == 1); |
| 1170 | return try self.readFloat(Type, 0); | 1170 | return try self.readFloat(Type, 0); |
| 1171 | }, | 1171 | }, |
| 1172 | .Bool => { | 1172 | .bool => { |
| 1173 | debug.assert(columns == 1); | 1173 | debug.assert(columns == 1); |
| 1174 | return try self.readBool(0); | 1174 | return try self.readBool(0); |
| 1175 | }, | 1175 | }, |
| 1176 | .Void => { | 1176 | .void => { |
| 1177 | debug.assert(columns == 1); | 1177 | debug.assert(columns == 1); |
| 1178 | }, | 1178 | }, |
| 1179 | .Array => { | 1179 | .array => { |
| 1180 | debug.assert(columns == 1); | 1180 | debug.assert(columns == 1); |
| 1181 | return try self.readArray(Type, 0); | 1181 | return try self.readArray(Type, 0); |
| 1182 | }, | 1182 | }, |
| 1183 | .Pointer => { | 1183 | .pointer => { |
| 1184 | debug.assert(columns == 1); | 1184 | debug.assert(columns == 1); |
| 1185 | return try self.readPointer(Type, .{ | 1185 | return try self.readPointer(Type, .{ |
| 1186 | .allocator = allocator, | 1186 | .allocator = allocator, |
| 1187 | }, 0); | 1187 | }, 0); |
| 1188 | }, | 1188 | }, |
| 1189 | .Enum => |TI| { | 1189 | .@"enum" => |TI| { |
| 1190 | debug.assert(columns == 1); | 1190 | debug.assert(columns == 1); |
| 1191 | 1191 | ||
| 1192 | const inner_value = try self.readField(Type.BaseType, .{ .allocator = allocator }, 0); | 1192 | const inner_value = try self.readField(Type.BaseType, .{ .allocator = allocator }, 0); |
| @@ -1198,13 +1198,13 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1198 | // TODO(vincent): don't use unreachable | 1198 | // TODO(vincent): don't use unreachable |
| 1199 | return std.meta.stringToEnum(Type, inner_value) orelse unreachable; | 1199 | return std.meta.stringToEnum(Type, inner_value) orelse unreachable; |
| 1200 | } | 1200 | } |
| 1201 | if (@typeInfo(Type.BaseType) == .Int) { | 1201 | if (@typeInfo(Type.BaseType) == .int) { |
| 1202 | return @enumFromInt(@as(TI.tag_type, @intCast(inner_value))); | 1202 | return @enumFromInt(@as(TI.tag_type, @intCast(inner_value))); |
| 1203 | } | 1203 | } |
| 1204 | @compileError("enum column " ++ @typeName(Type) ++ " must have a BaseType of either string or int"); | 1204 | @compileError("enum column " ++ @typeName(Type) ++ " must have a BaseType of either string or int"); |
| 1205 | }, | 1205 | }, |
| 1206 | .Struct => { | 1206 | .@"struct" => { |
| 1207 | std.debug.assert(columns == TypeInfo.Struct.fields.len); | 1207 | std.debug.assert(columns == TypeInfo.@"struct".fields.len); |
| 1208 | return try self.readStruct(.{ | 1208 | return try self.readStruct(.{ |
| 1209 | .allocator = allocator, | 1209 | .allocator = allocator, |
| 1210 | }); | 1210 | }); |
| @@ -1225,7 +1225,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1225 | 1225 | ||
| 1226 | var ret: ArrayType = undefined; | 1226 | var ret: ArrayType = undefined; |
| 1227 | switch (type_info) { | 1227 | switch (type_info) { |
| 1228 | .Array => |arr| { | 1228 | .array => |arr| { |
| 1229 | switch (arr.child) { | 1229 | switch (arr.child) { |
| 1230 | u8 => { | 1230 | u8 => { |
| 1231 | const size: usize = @intCast(c.sqlite3_column_bytes(self.stmt, i)); | 1231 | const size: usize = @intCast(c.sqlite3_column_bytes(self.stmt, i)); |
| @@ -1286,7 +1286,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1286 | // dupeWithSentinel is like dupe/dupeZ but allows for any sentinel value. | 1286 | // dupeWithSentinel is like dupe/dupeZ but allows for any sentinel value. |
| 1287 | fn dupeWithSentinel(comptime SliceType: type, allocator: mem.Allocator, data: []const u8) !SliceType { | 1287 | fn dupeWithSentinel(comptime SliceType: type, allocator: mem.Allocator, data: []const u8) !SliceType { |
| 1288 | switch (@typeInfo(SliceType)) { | 1288 | switch (@typeInfo(SliceType)) { |
| 1289 | .Pointer => |ptr_info| { | 1289 | .pointer => |ptr_info| { |
| 1290 | if (ptr_info.sentinel) |sentinel_ptr| { | 1290 | if (ptr_info.sentinel) |sentinel_ptr| { |
| 1291 | const sentinel = @as(*const ptr_info.child, @ptrCast(sentinel_ptr)).*; | 1291 | const sentinel = @as(*const ptr_info.child, @ptrCast(sentinel_ptr)).*; |
| 1292 | 1292 | ||
| @@ -1364,7 +1364,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1364 | 1364 | ||
| 1365 | var ret: PointerType = undefined; | 1365 | var ret: PointerType = undefined; |
| 1366 | switch (@typeInfo(PointerType)) { | 1366 | switch (@typeInfo(PointerType)) { |
| 1367 | .Pointer => |ptr| { | 1367 | .pointer => |ptr| { |
| 1368 | switch (ptr.size) { | 1368 | switch (ptr.size) { |
| 1369 | .One => { | 1369 | .One => { |
| 1370 | ret = try options.allocator.create(ptr.child); | 1370 | ret = try options.allocator.create(ptr.child); |
| @@ -1392,7 +1392,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1392 | 1392 | ||
| 1393 | var ret: OptionalType = undefined; | 1393 | var ret: OptionalType = undefined; |
| 1394 | switch (@typeInfo(OptionalType)) { | 1394 | switch (@typeInfo(OptionalType)) { |
| 1395 | .Optional => |opt| { | 1395 | .optional => |opt| { |
| 1396 | // Easy way to know if the column represents a null value. | 1396 | // Easy way to know if the column represents a null value. |
| 1397 | const value = c.sqlite3_column_value(self.stmt, @intCast(_i)); | 1397 | const value = c.sqlite3_column_value(self.stmt, @intCast(_i)); |
| 1398 | const datatype = c.sqlite3_value_type(value); | 1398 | const datatype = c.sqlite3_value_type(value); |
| @@ -1437,7 +1437,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1437 | 1437 | ||
| 1438 | var value: Type = undefined; | 1438 | var value: Type = undefined; |
| 1439 | 1439 | ||
| 1440 | inline for (@typeInfo(Type).Struct.fields, 0..) |field, _i| { | 1440 | inline for (@typeInfo(Type).@"struct".fields, 0..) |field, _i| { |
| 1441 | const i = @as(usize, _i); | 1441 | const i = @as(usize, _i); |
| 1442 | 1442 | ||
| 1443 | const ret = try self.readField(field.type, options, i); | 1443 | const ret = try self.readField(field.type, options, i); |
| @@ -1469,14 +1469,14 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1469 | break :blk try self.readBytes(Text, options.allocator, i, .Text); | 1469 | break :blk try self.readBytes(Text, options.allocator, i, .Text); |
| 1470 | }, | 1470 | }, |
| 1471 | else => switch (field_type_info) { | 1471 | else => switch (field_type_info) { |
| 1472 | .Int => try self.readInt(FieldType, i), | 1472 | .int => try self.readInt(FieldType, i), |
| 1473 | .Float => try self.readFloat(FieldType, i), | 1473 | .float => try self.readFloat(FieldType, i), |
| 1474 | .Bool => try self.readBool(i), | 1474 | .bool => try self.readBool(i), |
| 1475 | .Void => {}, | 1475 | .void => {}, |
| 1476 | .Array => try self.readArray(FieldType, i), | 1476 | .array => try self.readArray(FieldType, i), |
| 1477 | .Pointer => try self.readPointer(FieldType, options, i), | 1477 | .pointer => try self.readPointer(FieldType, options, i), |
| 1478 | .Optional => try self.readOptional(FieldType, options, i), | 1478 | .optional => try self.readOptional(FieldType, options, i), |
| 1479 | .Enum => |TI| { | 1479 | .@"enum" => |TI| { |
| 1480 | const inner_value = try self.readField(FieldType.BaseType, options, i); | 1480 | const inner_value = try self.readField(FieldType.BaseType, options, i); |
| 1481 | 1481 | ||
| 1482 | if (comptime isZigString(FieldType.BaseType)) { | 1482 | if (comptime isZigString(FieldType.BaseType)) { |
| @@ -1490,7 +1490,7 @@ pub fn Iterator(comptime Type: type) type { | |||
| 1490 | } | 1490 | } |
| 1491 | @compileError("enum column " ++ @typeName(FieldType) ++ " must have a BaseType of either string or int"); | 1491 | @compileError("enum column " ++ @typeName(FieldType) ++ " must have a BaseType of either string or int"); |
| 1492 | }, | 1492 | }, |
| 1493 | .Struct => |TI| { | 1493 | .@"struct" => |TI| { |
| 1494 | if (TI.layout == .@"packed") return @bitCast(try self.readInt(TI.backing_integer.?, i)); | 1494 | if (TI.layout == .@"packed") return @bitCast(try self.readInt(TI.backing_integer.?, i)); |
| 1495 | const inner_value = try self.readField(FieldType.BaseType, options, i); | 1495 | const inner_value = try self.readField(FieldType.BaseType, options, i); |
| 1496 | return try FieldType.readField(options.allocator, inner_value); | 1496 | return try FieldType.readField(options.allocator, inner_value); |
| @@ -1645,19 +1645,19 @@ pub const DynamicStatement = struct { | |||
| 1645 | return convertResultToError(result); | 1645 | return convertResultToError(result); |
| 1646 | }, | 1646 | }, |
| 1647 | else => switch (field_type_info) { | 1647 | else => switch (field_type_info) { |
| 1648 | .Int, .ComptimeInt => { | 1648 | .int, .comptime_int => { |
| 1649 | const result = c.sqlite3_bind_int64(self.stmt, column, @intCast(field)); | 1649 | const result = c.sqlite3_bind_int64(self.stmt, column, @intCast(field)); |
| 1650 | return convertResultToError(result); | 1650 | return convertResultToError(result); |
| 1651 | }, | 1651 | }, |
| 1652 | .Float, .ComptimeFloat => { | 1652 | .float, .comptime_float => { |
| 1653 | const result = c.sqlite3_bind_double(self.stmt, column, field); | 1653 | const result = c.sqlite3_bind_double(self.stmt, column, field); |
| 1654 | return convertResultToError(result); | 1654 | return convertResultToError(result); |
| 1655 | }, | 1655 | }, |
| 1656 | .Bool => { | 1656 | .bool => { |
| 1657 | const result = c.sqlite3_bind_int64(self.stmt, column, @intFromBool(field)); | 1657 | const result = c.sqlite3_bind_int64(self.stmt, column, @intFromBool(field)); |
| 1658 | return convertResultToError(result); | 1658 | return convertResultToError(result); |
| 1659 | }, | 1659 | }, |
| 1660 | .Pointer => |ptr| switch (ptr.size) { | 1660 | .pointer => |ptr| switch (ptr.size) { |
| 1661 | .One => { | 1661 | .One => { |
| 1662 | try self.bindField(ptr.child, options, field_name, i, field.*); | 1662 | try self.bindField(ptr.child, options, field_name, i, field.*); |
| 1663 | }, | 1663 | }, |
| @@ -1671,7 +1671,7 @@ pub const DynamicStatement = struct { | |||
| 1671 | }, | 1671 | }, |
| 1672 | else => @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType)), | 1672 | else => @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType)), |
| 1673 | }, | 1673 | }, |
| 1674 | .Array => |arr| switch (arr.child) { | 1674 | .array => |arr| switch (arr.child) { |
| 1675 | u8 => { | 1675 | u8 => { |
| 1676 | const data: []const u8 = field[0..field.len]; | 1676 | const data: []const u8 = field[0..field.len]; |
| 1677 | 1677 | ||
| @@ -1681,17 +1681,17 @@ pub const DynamicStatement = struct { | |||
| 1681 | }, | 1681 | }, |
| 1682 | else => @compileError("cannot bind field " ++ field_name ++ " of type array of " ++ @typeName(arr.child)), | 1682 | else => @compileError("cannot bind field " ++ field_name ++ " of type array of " ++ @typeName(arr.child)), |
| 1683 | }, | 1683 | }, |
| 1684 | .Optional => |opt| if (field) |non_null_field| { | 1684 | .optional => |opt| if (field) |non_null_field| { |
| 1685 | try self.bindField(opt.child, options, field_name, i, non_null_field); | 1685 | try self.bindField(opt.child, options, field_name, i, non_null_field); |
| 1686 | } else { | 1686 | } else { |
| 1687 | const result = c.sqlite3_bind_null(self.stmt, column); | 1687 | const result = c.sqlite3_bind_null(self.stmt, column); |
| 1688 | return convertResultToError(result); | 1688 | return convertResultToError(result); |
| 1689 | }, | 1689 | }, |
| 1690 | .Null => { | 1690 | .null => { |
| 1691 | const result = c.sqlite3_bind_null(self.stmt, column); | 1691 | const result = c.sqlite3_bind_null(self.stmt, column); |
| 1692 | return convertResultToError(result); | 1692 | return convertResultToError(result); |
| 1693 | }, | 1693 | }, |
| 1694 | .Enum => { | 1694 | .@"enum" => { |
| 1695 | if (comptime isZigString(FieldType.BaseType)) { | 1695 | if (comptime isZigString(FieldType.BaseType)) { |
| 1696 | try self.bindField(FieldType.BaseType, options, field_name, i, @tagName(field)); | 1696 | try self.bindField(FieldType.BaseType, options, field_name, i, @tagName(field)); |
| 1697 | } else if (@typeInfo(FieldType.BaseType) == .Int) { | 1697 | } else if (@typeInfo(FieldType.BaseType) == .Int) { |
| @@ -1700,7 +1700,7 @@ pub const DynamicStatement = struct { | |||
| 1700 | @compileError("enum column " ++ @typeName(FieldType) ++ " must have a BaseType of either string or int to bind"); | 1700 | @compileError("enum column " ++ @typeName(FieldType) ++ " must have a BaseType of either string or int to bind"); |
| 1701 | } | 1701 | } |
| 1702 | }, | 1702 | }, |
| 1703 | .Struct => |info| { | 1703 | .@"struct" => |info| { |
| 1704 | if (info.layout == .@"packed") { | 1704 | if (info.layout == .@"packed") { |
| 1705 | try self.bindField(info.backing_integer.?, options, field_name, i, @as(info.backing_integer.?, @bitCast(field))); | 1705 | try self.bindField(info.backing_integer.?, options, field_name, i, @as(info.backing_integer.?, @bitCast(field))); |
| 1706 | return; | 1706 | return; |
| @@ -1713,7 +1713,7 @@ pub const DynamicStatement = struct { | |||
| 1713 | 1713 | ||
| 1714 | try self.bindField(FieldType.BaseType, options, field_name, i, field_value); | 1714 | try self.bindField(FieldType.BaseType, options, field_name, i, field_value); |
| 1715 | }, | 1715 | }, |
| 1716 | .Union => |info| { | 1716 | .@"union" => |info| { |
| 1717 | if (info.tag_type) |UnionTagType| { | 1717 | if (info.tag_type) |UnionTagType| { |
| 1718 | inline for (info.fields) |u_field| { | 1718 | inline for (info.fields) |u_field| { |
| 1719 | // This wasn't entirely obvious when I saw code like this elsewhere, it works because of type coercion. | 1719 | // This wasn't entirely obvious when I saw code like this elsewhere, it works because of type coercion. |
| @@ -1771,7 +1771,7 @@ pub const DynamicStatement = struct { | |||
| 1771 | const Type = @TypeOf(values); | 1771 | const Type = @TypeOf(values); |
| 1772 | 1772 | ||
| 1773 | switch (@typeInfo(Type)) { | 1773 | switch (@typeInfo(Type)) { |
| 1774 | .Struct => |StructTypeInfo| { | 1774 | .@"struct" => |StructTypeInfo| { |
| 1775 | inline for (StructTypeInfo.fields, 0..) |struct_field, struct_field_i| { | 1775 | inline for (StructTypeInfo.fields, 0..) |struct_field, struct_field_i| { |
| 1776 | const field_value = @field(values, struct_field.name); | 1776 | const field_value = @field(values, struct_field.name); |
| 1777 | 1777 | ||
| @@ -1783,7 +1783,7 @@ pub const DynamicStatement = struct { | |||
| 1783 | } | 1783 | } |
| 1784 | } | 1784 | } |
| 1785 | }, | 1785 | }, |
| 1786 | .Pointer => |PointerTypeInfo| { | 1786 | .pointer => |PointerTypeInfo| { |
| 1787 | switch (PointerTypeInfo.size) { | 1787 | switch (PointerTypeInfo.size) { |
| 1788 | .Slice => { | 1788 | .Slice => { |
| 1789 | for (values, 0..) |value_to_bind, index| { | 1789 | for (values, 0..) |value_to_bind, index| { |
| @@ -1793,7 +1793,7 @@ pub const DynamicStatement = struct { | |||
| 1793 | else => @compileError("TODO support pointer size " ++ @tagName(PointerTypeInfo.size)), | 1793 | else => @compileError("TODO support pointer size " ++ @tagName(PointerTypeInfo.size)), |
| 1794 | } | 1794 | } |
| 1795 | }, | 1795 | }, |
| 1796 | .Array => |ArrayTypeInfo| { | 1796 | .array => |ArrayTypeInfo| { |
| 1797 | for (values, 0..) |value_to_bind, index| { | 1797 | for (values, 0..) |value_to_bind, index| { |
| 1798 | try self.bindField(ArrayTypeInfo.child, options, "unknown", @intCast(index), value_to_bind); | 1798 | try self.bindField(ArrayTypeInfo.child, options, "unknown", @intCast(index), value_to_bind); |
| 1799 | } | 1799 | } |
| @@ -2067,7 +2067,7 @@ pub fn Statement(comptime opts: StatementOptions, comptime query: anytype) type | |||
| 2067 | @compileError("options passed to Statement.bind must be a struct (DynamicStatement supports runtime slices)"); | 2067 | @compileError("options passed to Statement.bind must be a struct (DynamicStatement supports runtime slices)"); |
| 2068 | } | 2068 | } |
| 2069 | 2069 | ||
| 2070 | const StructTypeInfo = @typeInfo(StructType).Struct; | 2070 | const StructTypeInfo = @typeInfo(StructType).@"struct"; |
| 2071 | 2071 | ||
| 2072 | if (comptime query.bind_markers.len != StructTypeInfo.fields.len) { | 2072 | if (comptime query.bind_markers.len != StructTypeInfo.fields.len) { |
| 2073 | @compileError(std.fmt.comptimePrint("expected {d} bind parameters but got {d}", .{ | 2073 | @compileError(std.fmt.comptimePrint("expected {d} bind parameters but got {d}", .{ |
| @@ -2081,7 +2081,7 @@ pub fn Statement(comptime opts: StatementOptions, comptime query: anytype) type | |||
| 2081 | if (bind_marker.typed) |typ| { | 2081 | if (bind_marker.typed) |typ| { |
| 2082 | const FieldTypeInfo = @typeInfo(struct_field.type); | 2082 | const FieldTypeInfo = @typeInfo(struct_field.type); |
| 2083 | switch (FieldTypeInfo) { | 2083 | switch (FieldTypeInfo) { |
| 2084 | .Struct, .Enum, .Union => comptime assertMarkerType( | 2084 | .@"struct", .@"enum", .@"union" => comptime assertMarkerType( |
| 2085 | if (@hasDecl(struct_field.type, "BaseType")) struct_field.type.BaseType else struct_field.type, | 2085 | if (@hasDecl(struct_field.type, "BaseType")) struct_field.type.BaseType else struct_field.type, |
| 2086 | typ, | 2086 | typ, |
| 2087 | ), | 2087 | ), |
| @@ -2667,10 +2667,10 @@ test "sqlite: read a single text value" { | |||
| 2667 | else => { | 2667 | else => { |
| 2668 | const type_info = @typeInfo(typ); | 2668 | const type_info = @typeInfo(typ); |
| 2669 | switch (type_info) { | 2669 | switch (type_info) { |
| 2670 | .Pointer => { | 2670 | .pointer => { |
| 2671 | try testing.expectEqualStrings("Vincent", name.?); | 2671 | try testing.expectEqualStrings("Vincent", name.?); |
| 2672 | }, | 2672 | }, |
| 2673 | .Array => |arr| if (arr.sentinel) |sentinel_ptr| { | 2673 | .array => |arr| if (arr.sentinel) |sentinel_ptr| { |
| 2674 | const sentinel = @as(*const arr.child, @ptrCast(sentinel_ptr)).*; | 2674 | const sentinel = @as(*const arr.child, @ptrCast(sentinel_ptr)).*; |
| 2675 | const res = mem.sliceTo(&name.?, sentinel); | 2675 | const res = mem.sliceTo(&name.?, sentinel); |
| 2676 | try testing.expectEqualStrings("Vincent", res); | 2676 | try testing.expectEqualStrings("Vincent", res); |
| @@ -322,7 +322,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 322 | @compileError("the Cursor type must have an init function, " ++ error_message); | 322 | @compileError("the Cursor type must have an init function, " ++ error_message); |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | const info = @typeInfo(@TypeOf(Cursor.init)).Fn; | 325 | const info = @typeInfo(@TypeOf(Cursor.init)).@"fn"; |
| 326 | 326 | ||
| 327 | if (info.params.len != 2) @compileError(error_message); | 327 | if (info.params.len != 2) @compileError(error_message); |
| 328 | if (info.params[0].type.? != mem.Allocator) @compileError(error_message); | 328 | if (info.params[0].type.? != mem.Allocator) @compileError(error_message); |
| @@ -340,7 +340,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 340 | @compileError("the Cursor type must have a deinit function, " ++ error_message); | 340 | @compileError("the Cursor type must have a deinit function, " ++ error_message); |
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | const info = @typeInfo(@TypeOf(Cursor.deinit)).Fn; | 343 | const info = @typeInfo(@TypeOf(Cursor.deinit)).@"fn"; |
| 344 | 344 | ||
| 345 | if (info.params.len != 1) @compileError(error_message); | 345 | if (info.params.len != 1) @compileError(error_message); |
| 346 | if (info.params[0].type.? != *Cursor) @compileError(error_message); | 346 | if (info.params[0].type.? != *Cursor) @compileError(error_message); |
| @@ -361,7 +361,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 361 | @compileError("the Cursor type must have a next function, " ++ error_message); | 361 | @compileError("the Cursor type must have a next function, " ++ error_message); |
| 362 | } | 362 | } |
| 363 | 363 | ||
| 364 | const info = @typeInfo(@TypeOf(Cursor.next)).Fn; | 364 | const info = @typeInfo(@TypeOf(Cursor.next)).@"fn"; |
| 365 | 365 | ||
| 366 | if (info.params.len != 2) @compileError(error_message); | 366 | if (info.params.len != 2) @compileError(error_message); |
| 367 | if (info.params[0].type.? != *Cursor) @compileError(error_message); | 367 | if (info.params[0].type.? != *Cursor) @compileError(error_message); |
| @@ -383,7 +383,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 383 | @compileError("the Cursor type must have a hasNext function, " ++ error_message); | 383 | @compileError("the Cursor type must have a hasNext function, " ++ error_message); |
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | const info = @typeInfo(@TypeOf(Cursor.hasNext)).Fn; | 386 | const info = @typeInfo(@TypeOf(Cursor.hasNext)).@"fn"; |
| 387 | 387 | ||
| 388 | if (info.params.len != 2) @compileError(error_message); | 388 | if (info.params.len != 2) @compileError(error_message); |
| 389 | if (info.params[0].type.? != *Cursor) @compileError(error_message); | 389 | if (info.params[0].type.? != *Cursor) @compileError(error_message); |
| @@ -405,7 +405,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 405 | @compileError("the Cursor type must have a filter function, " ++ error_message); | 405 | @compileError("the Cursor type must have a filter function, " ++ error_message); |
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | const info = @typeInfo(@TypeOf(Cursor.filter)).Fn; | 408 | const info = @typeInfo(@TypeOf(Cursor.filter)).@"fn"; |
| 409 | 409 | ||
| 410 | if (info.params.len != 4) @compileError(error_message); | 410 | if (info.params.len != 4) @compileError(error_message); |
| 411 | if (info.params[0].type.? != *Cursor) @compileError(error_message); | 411 | if (info.params[0].type.? != *Cursor) @compileError(error_message); |
| @@ -432,7 +432,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 432 | @compileError("the Cursor type must have a column function, " ++ error_message); | 432 | @compileError("the Cursor type must have a column function, " ++ error_message); |
| 433 | } | 433 | } |
| 434 | 434 | ||
| 435 | const info = @typeInfo(@TypeOf(Cursor.column)).Fn; | 435 | const info = @typeInfo(@TypeOf(Cursor.column)).@"fn"; |
| 436 | 436 | ||
| 437 | if (info.params.len != 3) @compileError(error_message); | 437 | if (info.params.len != 3) @compileError(error_message); |
| 438 | if (info.params[0].type.? != *Cursor) @compileError(error_message); | 438 | if (info.params[0].type.? != *Cursor) @compileError(error_message); |
| @@ -455,7 +455,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 455 | @compileError("the Cursor type must have a rowId function, " ++ error_message); | 455 | @compileError("the Cursor type must have a rowId function, " ++ error_message); |
| 456 | } | 456 | } |
| 457 | 457 | ||
| 458 | const info = @typeInfo(@TypeOf(Cursor.rowId)).Fn; | 458 | const info = @typeInfo(@TypeOf(Cursor.rowId)).@"fn"; |
| 459 | 459 | ||
| 460 | if (info.params.len != 2) @compileError(error_message); | 460 | if (info.params.len != 2) @compileError(error_message); |
| 461 | if (info.params[0].type.? != *Cursor) @compileError(error_message); | 461 | if (info.params[0].type.? != *Cursor) @compileError(error_message); |
| @@ -480,7 +480,7 @@ fn validateTableType(comptime Table: type) void { | |||
| 480 | @compileError("the Table type must have a init function, " ++ error_message); | 480 | @compileError("the Table type must have a init function, " ++ error_message); |
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | const info = @typeInfo(@TypeOf(Table.init)).Fn; | 483 | const info = @typeInfo(@TypeOf(Table.init)).@"fn"; |
| 484 | 484 | ||
| 485 | if (info.params.len != 3) @compileError(error_message); | 485 | if (info.params.len != 3) @compileError(error_message); |
| 486 | if (info.params[0].type.? != mem.Allocator) @compileError(error_message); | 486 | if (info.params[0].type.? != mem.Allocator) @compileError(error_message); |
| @@ -500,7 +500,7 @@ fn validateTableType(comptime Table: type) void { | |||
| 500 | @compileError("the Table type must have a deinit function, " ++ error_message); | 500 | @compileError("the Table type must have a deinit function, " ++ error_message); |
| 501 | } | 501 | } |
| 502 | 502 | ||
| 503 | const info = @typeInfo(@TypeOf(Table.deinit)).Fn; | 503 | const info = @typeInfo(@TypeOf(Table.deinit)).@"fn"; |
| 504 | 504 | ||
| 505 | if (info.params.len != 2) @compileError(error_message); | 505 | if (info.params.len != 2) @compileError(error_message); |
| 506 | if (info.params[0].type.? != *Table) @compileError(error_message); | 506 | if (info.params[0].type.? != *Table) @compileError(error_message); |
| @@ -522,7 +522,7 @@ fn validateTableType(comptime Table: type) void { | |||
| 522 | @compileError("the Table type must have a buildBestIndex function, " ++ error_message); | 522 | @compileError("the Table type must have a buildBestIndex function, " ++ error_message); |
| 523 | } | 523 | } |
| 524 | 524 | ||
| 525 | const info = @typeInfo(@TypeOf(Table.buildBestIndex)).Fn; | 525 | const info = @typeInfo(@TypeOf(Table.buildBestIndex)).@"fn"; |
| 526 | 526 | ||
| 527 | if (info.params.len != 3) @compileError(error_message); | 527 | if (info.params.len != 3) @compileError(error_message); |
| 528 | if (info.params[0].type.? != *Table) @compileError(error_message); | 528 | if (info.params[0].type.? != *Table) @compileError(error_message); |
| @@ -929,7 +929,7 @@ pub fn VirtualTable( | |||
| 929 | // TODO(vincent): does it make sense to put this in setResult ? Functions could also return a union. | 929 | // TODO(vincent): does it make sense to put this in setResult ? Functions could also return a union. |
| 930 | const ColumnType = @TypeOf(column); | 930 | const ColumnType = @TypeOf(column); |
| 931 | switch (@typeInfo(ColumnType)) { | 931 | switch (@typeInfo(ColumnType)) { |
| 932 | .Union => |info| { | 932 | .@"union" => |info| { |
| 933 | if (info.tag_type) |UnionTagType| { | 933 | if (info.tag_type) |UnionTagType| { |
| 934 | inline for (info.fields) |u_field| { | 934 | inline for (info.fields) |u_field| { |
| 935 | 935 | ||