diff options
author | Ekaitz Zarraga <ekaitz@elenq.tech> | 2024-08-05 22:20:19 +0200 |
---|---|---|
committer | Ekaitz Zarraga <ekaitz@elenq.tech> | 2024-08-05 22:20:46 +0200 |
commit | 8efa7cb0013aae1708e2d815b7fa65f055062159 (patch) | |
tree | 4b815a71d8d09b00a29d9435f5b52369fa482081 /src/duckdb/Column.zig | |
parent | 2c5149d5ca84b28d371dffa2c5ea3cae53c93a8e (diff) |
Results with proper conversion
Diffstat (limited to 'src/duckdb/Column.zig')
-rw-r--r-- | src/duckdb/Column.zig | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/src/duckdb/Column.zig b/src/duckdb/Column.zig new file mode 100644 index 0000000..fb505bb --- /dev/null +++ b/src/duckdb/Column.zig @@ -0,0 +1,204 @@ +const std = @import("std"); +const c = @cImport({ + @cInclude("duckdb.h"); +}); + + +const DuckdbType = enum { + BOOLEAN, + TINYINT, + SMALLINT, + INTEGER, + BIGINT, + UTINYINT, + USMALLINT, + UINTEGER, + UBIGINT, + FLOAT, + DOUBLE, + TIMESTAMP, + DATE, + TIME, + INTERVAL, + HUGEINT, + UHUGEINT, + VARCHAR, + BLOB, + TIMESTAMP_S, + TIMESTAMP_MS, + TIMESTAMP_NS, + UUID, + TIME_TZ, + TIMESTAMP_TZ, +}; + +pub const Column = union(DuckdbType) { + BOOLEAN: [*]bool, + TINYINT: [*]i8, + SMALLINT: [*]i16, + INTEGER: [*]i32, + BIGINT: [*]i64, + UTINYINT: [*]u8, + USMALLINT: [*]u16, + UINTEGER: [*]u32, + UBIGINT: [*]u64, + FLOAT: [*]f32, + DOUBLE: [*]f64, + TIMESTAMP: [*]c.duckdb_timestamp, + DATE: [*]c.duckdb_date, + TIME: [*]c.duckdb_time, + INTERVAL: [*]c.duckdb_interval, + HUGEINT: [*]c.duckdb_hugeint, + UHUGEINT: [*]c.duckdb_uhugeint, + VARCHAR: [*]c.duckdb_string_t, + BLOB: [*]c.duckdb_string_t, + TIMESTAMP_S: [*]c.duckdb_timestamp, + TIMESTAMP_MS: [*]c.duckdb_timestamp, + TIMESTAMP_NS: [*]c.duckdb_timestamp, + UUID: [*]c.duckdb_hugeint, + TIME_TZ: [*]c.duckdb_time_tz, + TIMESTAMP_TZ: [*]c.duckdb_timestamp, + + const Self = @This(); + + pub fn fromType(column_type: c.DUCKDB_TYPE, column: *anyopaque) Column { + return switch (column_type) { + c.DUCKDB_TYPE_BOOLEAN => .{.BOOLEAN = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_TINYINT => .{.TINYINT = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_SMALLINT => .{.SMALLINT = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_INTEGER => .{.INTEGER = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_BIGINT => .{.BIGINT = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_UTINYINT => .{.UTINYINT = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_USMALLINT => .{.USMALLINT = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_UINTEGER => .{.UINTEGER = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_UBIGINT => .{.UBIGINT = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_FLOAT => .{.FLOAT = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_DOUBLE => .{.DOUBLE = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_VARCHAR => .{.VARCHAR = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_BLOB => .{.BLOB = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_TIMESTAMP => .{.TIMESTAMP = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_DATE => .{.DATE = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_TIME => .{.TIME = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_INTERVAL => .{.INTERVAL = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_HUGEINT => .{.HUGEINT = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_UHUGEINT => .{.UHUGEINT = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_TIMESTAMP_S => .{.TIMESTAMP_S = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_TIMESTAMP_MS => .{.TIMESTAMP_MS = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_TIMESTAMP_NS => .{.TIMESTAMP_NS = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_UUID => .{.UUID = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_TIME_TZ => .{.TIME_TZ = @alignCast(@ptrCast(column))}, + c.DUCKDB_TYPE_TIMESTAMP_TZ => .{.TIMESTAMP_TZ = @alignCast(@ptrCast(column))}, + else => unreachable, + }; + } + + pub fn getAs(self: Self, i: usize, T: anytype) !T{ + const ti : std.builtin.Type = @typeInfo(T); + switch (self){ + .BOOLEAN + => |ptr| switch(ti) { + .Bool => return ptr[i], + .Int => return @intFromBool(ptr[i]), + else => return error.InvalidConversion, + }, + .TINYINT + => |ptr| switch(ti) { + .Int => return @intCast(ptr[i]), + .Float => return @floatFromInt(ptr[i]), + else => return error.InvalidConversion, + }, + .SMALLINT + => |ptr| switch(ti) { + .Int => return @intCast(ptr[i]), + .Float => return @floatFromInt(ptr[i]), + else => return error.InvalidConversion, + }, + .INTEGER + => |ptr| switch(ti) { + .Int => return @intCast(ptr[i]), + .Float => return @floatFromInt(ptr[i]), + else => return error.InvalidConversion, + }, + .BIGINT + => |ptr| switch(ti) { + .Int => return @intCast(ptr[i]), + .Float => return @floatFromInt(ptr[i]), + else => return error.InvalidConversion, + }, + .UTINYINT + => |ptr| switch(ti) { + .Int => return @intCast(ptr[i]), + .Float => return @floatFromInt(ptr[i]), + else => return error.InvalidConversion, + }, + .USMALLINT + => |ptr| switch(ti) { + .Int => return @intCast(ptr[i]), + .Float => return @floatFromInt(ptr[i]), + else => return error.InvalidConversion, + }, + .UINTEGER + => |ptr| switch(ti) { + .Int => return @intCast(ptr[i]), + .Float => return @floatFromInt(ptr[i]), + else => return error.InvalidConversion, + }, + .UBIGINT + => |ptr| switch(ti) { + .Int => return @intCast(ptr[i]), + .Float => return @floatFromInt(ptr[i]), + else => return error.InvalidConversion, + }, + .FLOAT + => |ptr| switch(ti) { + .Int => return @intFromFloat(ptr[i]), + .Float => return @floatCast(ptr[i]), + else => return error.InvalidConversion, + }, + .DOUBLE + => |ptr| switch(ti) { + .Int => return @intFromFloat(ptr[i]), + .Float => return @floatCast(ptr[i]), + else => return error.InvalidConversion, + }, + .VARCHAR, + .BLOB + => |ptr| switch(ti){ + .Pointer => |p| switch (p.size) { + .Slice => { + if ( p.child == u8 ) { + var result: T = undefined; + if (c.duckdb_string_is_inlined(ptr[i])){ + result = &ptr[i].value.inlined.inlined; + result.len = ptr[i].value.inlined.length; + return result; + } else { + result.len = ptr[i].value.pointer.length; + result.ptr = ptr[i].value.pointer.ptr; + return result; + } + } else { + @compileError("Invalid type for output data: " + ++ @typeName(T)); + } + }, + else => return error.InvalidConversion, + }, + else => return error.InvalidConversion, + }, + .TIMESTAMP, + .DATE, + .TIME, + .INTERVAL, + .HUGEINT, + .UHUGEINT, + .TIMESTAMP_S, + .TIMESTAMP_MS, + .TIMESTAMP_NS, + .UUID, + .TIME_TZ, + .TIMESTAMP_TZ => + return error.ConversionNotImplemented, + } + } +}; |