From 5279117c555669dc3d6ad6efba29a83f2a333fbd Mon Sep 17 00:00:00 2001 From: Zack Fu Zi Xiang Date: Mon, 28 Oct 2024 22:00:04 +0800 Subject: [PATCH] feat: fix runtime parameters --- .github/workflows/integrations.yml | 8 +---- .github/workflows/unit_test.yml | 3 +- integration_tests/conn.zig | 6 +++- src/protocol/prepared_statements.zig | 50 ++++++++-------------------- 4 files changed, 20 insertions(+), 47 deletions(-) diff --git a/.github/workflows/integrations.yml b/.github/workflows/integrations.yml index 321cc28..f10428f 100644 --- a/.github/workflows/integrations.yml +++ b/.github/workflows/integrations.yml @@ -2,11 +2,6 @@ name: Integration Tests on: push: - branches: - - main - pull_request: - branches: - - main jobs: build: @@ -20,8 +15,7 @@ jobs: - name: install zig run: | - ZIG_VERSION=0.12.0 - wget https://ziglang.org/builds/zig-linux-x86_64-$ZIG_VERSION.tar.xz + wget https://ziglang.org/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz tar xf zig-linux-x86_64-$ZIG_VERSION.tar.xz mv zig-linux-x86_64-$ZIG_VERSION $HOME/zig-build diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml index dfbbbfa..50b7e6c 100644 --- a/.github/workflows/unit_test.yml +++ b/.github/workflows/unit_test.yml @@ -15,8 +15,7 @@ jobs: - uses: actions/checkout@v3 - name: install zig run: | - ZIG_VERSION=0.12.0-dev.3291+17bad9f88 - wget https://ziglang.org/builds/zig-linux-x86_64-$ZIG_VERSION.tar.xz + wget https://ziglang.org/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz tar xf zig-linux-x86_64-$ZIG_VERSION.tar.xz mv zig-linux-x86_64-$ZIG_VERSION $HOME/zig-build diff --git a/integration_tests/conn.zig b/integration_tests/conn.zig index 2725bea..f62be50 100644 --- a/integration_tests/conn.zig +++ b/integration_tests/conn.zig @@ -696,7 +696,7 @@ test "select concat with params" { const prep_res = try c.prepare(allocator, "SELECT CONCAT(?, ?) AS col1"); defer prep_res.deinit(allocator); const prep_stmt = try prep_res.expect(.stmt); - const res = try c.executeRows(&prep_stmt, .{ "hello", "world" }); + const res = try c.executeRows(&prep_stmt, .{ runtimeValue("hello"), runtimeValue("world") }); const rows: ResultSet(BinaryResultRow) = try res.expect(.rows); const rows_iter = rows.iter(); @@ -707,3 +707,7 @@ test "select concat with params" { try std.testing.expectEqualDeep(expected, structs.struct_list.items); } } + +fn runtimeValue(a: anytype) @TypeOf(a) { + return a; +} diff --git a/src/protocol/prepared_statements.zig b/src/protocol/prepared_statements.zig index aafce11..ecf576e 100644 --- a/src/protocol/prepared_statements.zig +++ b/src/protocol/prepared_statements.zig @@ -111,19 +111,13 @@ pub const ExecuteRequest = struct { //if (e.new_params_bind_flag > 0) { comptime var enum_field_types: [params.len]constants.EnumFieldType = undefined; inline for (params, &enum_field_types) |param, *enum_field_type| { - enum_field_type.* = comptime enumFieldTypeFromParam(param); + enum_field_type.* = comptime enumFieldTypeFromParam(@TypeOf(param)); } inline for (enum_field_types, params) |enum_field_type, param| { try writer.writeInt(u8, @intFromEnum(enum_field_type)); const sign_flag = comptime switch (@typeInfo(@TypeOf(param))) { - .ComptimeInt => switch (enum_field_type) { - .MYSQL_TYPE_TINY => if (param > maxInt(i8)) 0x80 else 0, - .MYSQL_TYPE_SHORT => if (param > maxInt(i16)) 0x80 else 0, - .MYSQL_TYPE_LONG => if (param > maxInt(i32)) 0x80 else 0, - .MYSQL_TYPE_LONGLONG => if (param > maxInt(i64)) 0x80 else 0, - else => 0, - }, + .ComptimeInt => if (param > maxInt(i64)) 0x80 else 0, .Int => |int| if (int.signedness == .unsigned) 0x80 else 0, else => 0, }; @@ -146,10 +140,11 @@ pub const ExecuteRequest = struct { // TODO: Write params and attr as binary values // Write params as binary values inline for (params, enum_field_types) |param, enum_field_type| { - // if (enum_field_type == constants.EnumFieldType.MYSQL_TYPE_NULL) { - // continue; - // } - try writeParamAsFieldType(writer, enum_field_type, param); + if (isNull(param)) { + try writeParamAsFieldType(writer, constants.EnumFieldType.MYSQL_TYPE_NULL, param); + } else { + try writeParamAsFieldType(writer, enum_field_type, param); + } } // if (has_attributes_to_write) { @@ -161,21 +156,14 @@ pub const ExecuteRequest = struct { } }; -fn enumFieldTypeFromParam(param: anytype) constants.EnumFieldType { - const Param = @TypeOf(param); +fn enumFieldTypeFromParam(Param: type) constants.EnumFieldType { const param_type_info = @typeInfo(Param); return switch (Param) { DateTime => constants.EnumFieldType.MYSQL_TYPE_DATETIME, Duration => constants.EnumFieldType.MYSQL_TYPE_TIME, else => switch (param_type_info) { .Null => return constants.EnumFieldType.MYSQL_TYPE_NULL, - .Optional => { - if (param) |p| { - return enumFieldTypeFromParam(p); - } else { - return constants.EnumFieldType.MYSQL_TYPE_NULL; - } - }, + .Optional => |o| return enumFieldTypeFromParam(o.child), .Int => |int| { if (int.bits <= 8) { return constants.EnumFieldType.MYSQL_TYPE_TINY; @@ -187,19 +175,7 @@ fn enumFieldTypeFromParam(param: anytype) constants.EnumFieldType { return constants.EnumFieldType.MYSQL_TYPE_LONGLONG; } }, - .ComptimeInt => { - if (std.math.minInt(i8) <= param and param <= std.math.maxInt(u8)) { - return constants.EnumFieldType.MYSQL_TYPE_TINY; - } else if (std.math.minInt(i16) <= param and param <= std.math.maxInt(u16)) { - return constants.EnumFieldType.MYSQL_TYPE_SHORT; - } else if (std.math.minInt(i32) <= param and param <= std.math.maxInt(u32)) { - return constants.EnumFieldType.MYSQL_TYPE_LONG; - } else if (std.math.minInt(i64) <= param and param <= std.math.maxInt(u64)) { - return constants.EnumFieldType.MYSQL_TYPE_LONGLONG; - } else { - @compileLog("hello"); - } - }, + .ComptimeInt => return constants.EnumFieldType.MYSQL_TYPE_LONGLONG, .Float => |float| { if (float.bits <= 32) { return constants.EnumFieldType.MYSQL_TYPE_FLOAT; @@ -221,7 +197,7 @@ fn enumFieldTypeFromParam(param: anytype) constants.EnumFieldType { .Enum => return constants.EnumFieldType.MYSQL_TYPE_STRING, .Pointer => |pointer| { switch (pointer.size) { - .One => return enumFieldTypeFromParam(param.*), + .One => return enumFieldTypeFromParam(pointer.child), else => {}, } switch (@typeInfo(pointer.child)) { @@ -237,7 +213,7 @@ fn enumFieldTypeFromParam(param: anytype) constants.EnumFieldType { } }, else => { - @compileLog(param); + @compileLog(Param); @compileError("unsupported type"); }, }, @@ -471,7 +447,7 @@ pub fn nullBitsParamsAttrs(params: anytype, start: usize, attrs: []const BinaryP } inline fn isNull(param: anytype) bool { - return switch (@typeInfo(@TypeOf(param))) { + return comptime switch (@typeInfo(@TypeOf(param))) { inline .Optional => if (param) |p| isNull(p) else true, inline .Null => true, inline else => false,