Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【Zig 日报】 2024-03-16 使用 Zig 开发 PostgreSQL 插件 #103

Open
jiacai2050 opened this issue Mar 16, 2024 · 0 comments
Open

【Zig 日报】 2024-03-16 使用 Zig 开发 PostgreSQL 插件 #103

jiacai2050 opened this issue Mar 16, 2024 · 0 comments

Comments

@jiacai2050
Copy link
Member

pgzx 是一个使用 Zig 编写的 PostgreSQL 扩展库。它提供了一套实用程序(如错误处理、内存分配器、封装器)和一个开发环境,可简化与 PostgreSQL 代码库的集成。

如果浏览一下 Postgres 的源代码,就会发现 PG_TRY / PG_CATCH / PG_FINALLY 宏被用作 C 语言的一种 "异常处理 "形式,用于捕捉 ereport 系列函数引发的错误。这些宏使用 longjump(即跨越函数边界的跳转)来实现 "catch/finally " 效果。

这意味着我们从 Zig 中调用 Postgres 函数时需要小心。例如,如果被调用的 C 函数引发了 ereport 错误,longjmp 可能会跳过清理资源的 Zig 代码(如 errdefer)。pgzx 推荐这么来处理

    var errctx = pgzx.err.Context.init();
    defer errctx.deinit();
    if (errctx.pg_try()) {
        // zig code that calls several Postgres C functions.
    } else {
        return errctx.errorValue();
    }

一个更完整的示例:

SELECT char_count_zig('Hello, World', 'o');
 char_count_zig
----------------
              2
(1 row)

实现代码

const std = @import("std");
const pgzx = @import("pgzx");

comptime {
    pgzx.PG_MODULE_MAGIC();

    pgzx.PG_FUNCTION_V1("char_count_zig", char_count_zig);
}

fn char_count_zig(input_text: []const u8, target_char: []const u8) !u32 {
    if (target_char.len > 1) {
        return pgzx.elog.Error(@src(), "Target char is more than one byte", .{});
    }

    pgzx.elog.Info(@src(), "input_text: {s}\n", .{input_text});
    pgzx.elog.Info(@src(), "target_char: {s}\n", .{target_char});
    pgzx.elog.Info(@src(), "Target char len: {}\n", .{target_char.len});

    var count: u32 = 0;
    for (input_text) |char| {
        if (char == target_char[0]) {
            count += 1;
        }
    }
    return count;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant