2025年9月25日: PostgreSQL 18 发布!

pl/dotnet v0.99 (beta) 发布公告

发布于 2024-04-09,作者:Brick Abode
相关开源项目

pl/dotnet v0.99 (beta) 发布公告

pl/dotnet 为 PostgreSQL 增加了对 C# 和 F# 的全面支持。0.99 是我们的公开 beta 版本;我们希望与世界分享它的神奇之处。

  • 我们支持所有 PL 操作:函数、过程、DO、SPI、触发器、记录、SRF、OUT/INOUT、表函数等。
  • 我们原生支持 46 种标准用户类型中的 40 种,这是外部 PL 中最多的。
  • 完全兼容 NPGSQL,SPI 通过 NPGSQL API 暴露,以实现最大的兼容性。
  • 在我们的基准测试中,C# 和 F# 是 PostgreSQL 中最快的过程语言。
  • 所有功能都经过 C# 和 F# 的全面测试,共有 1013 个单元测试。
  • 基于 PostgreSQL 许可证的 100% 免费软件。

这是一个 beta 版本;我们欢迎使用并期待您的反馈。

如何获取

更多详情如下。

使用示例

pl/dotnet 让您在 PostgreSQL 的过程、函数和触发器中拥有 C# 和 F# 的全部强大功能。

CREATE OR REPLACE FUNCTION dynamic_record_generator_srf(lim INT8)  
RETURNS SETOF record  
AS $$  
    upperLimit = lim.HasValue ? lim : System.Int32.MaxValue;  
    for(long i=0;i<upperLimit;i++){ yield return new object?[] { i, $"Number is {i}" }; }  
$$ LANGUAGE plcsharp;

CREATE OR REPLACE FUNCTION dynamic_record_generator_srf_fsharp(lim INT8)  
RETURNS SETOF record  
AS $$  
    let upperLimit = Option.defaultValue (int64 System.Int32.MaxValue) lim  
    seq { for i in 0L .. upperLimit - 1L do yield [| box i; $"Number is {i}" |] }  
$$ LANGUAGE plfsharp;

SQL 功能

我们支持所有 SQL 函数模式。

  • 普通过程和函数
  • 触发器函数,提供完整的触发器支持:触发器参数、旧/新行、行重写(允许的情况下),以及所有标准的触发器信息。
  • 返回集合的函数,在 C# 中良好地映射为迭代器,在 F# 中映射为序列。
  • 表函数,以及返回记录或记录集合的函数。
  • 完全支持 IN/OUT/INOUT 函数。

数据类型支持

我们支持 40 种 PostgreSQL 类型,所有类型都映射到它们的 NPGSQL 标准 dotnet 类型。唯一值得注意的例外是 multirange、enum 和 struct 类型,我们希望将来能添加它们。所有数据类型都允许为 null,具有完整的数组支持,并且已通过 C# 和 F# 的全面单元测试。(出于技术原因,此处以 (PostgreSQL 类型: Dotnet 类型) 的列表形式展示,而不是表格。)

  • bit: BitArray
  • bool: Bool
  • box: NpgsqlBox
  • bpchar: String
  • bytea: Byte[]
  • cidr: (IPAddress Address, Int Netmask)
  • circle: NpgsqlCircle
  • date: DateOnly
  • daterange: NpgsqlRange<DateOnly>
  • float4: Float
  • float8: Double
  • inet: (IPAddress Address, Int Netmask)
  • int2: Short
  • int4: Int
  • int4range: NpgsqlRange<Int>
  • int8: Long
  • int8range: NpgsqlRange<Long>
  • interval: NpgsqlInterval
  • json: String
  • line: NpgsqlLine
  • lseg: NpgsqlLSeg
  • macaddr8: PhysicalAddress
  • macaddr: PhysicalAddress
  • money: Decimal
  • path: NpgsqlPath
  • point: NpgsqlPoint
  • polygon: NpgsqlPolygon
  • record: Object?[]
  • text: String
  • timestamp: DateTime
  • timestamptz: DateTime
  • time: TimeOnly
  • timetz: DateTimeOffset
  • tsrange: NpgsqlRange<DateTime>
  • tstzrange: NpgsqlRange<DateTime>
  • uuid: Guid
  • varbit: BitArray
  • varchar: String
  • void: Void
  • xml: String

SPI

我们的 SPI 利用 NPGSQL 客户端库提供了一个原生的 dotnet 实现,与现有客户端代码具有最大的兼容性。我们在非常低的级别拦截了 NPGSQL 调用,用 SPI 调用替换了客户端协议处理;否则,NPGSQL 保持不变。我们将 NPGSQL 测试套件导入为存储过程,并将其用于我们的测试,这使我们对兼容性水平有了很好的了解。

为了提高兼容性和添加功能,还有一些工作要做。我们 NPGSQL 测试中持续失败的最大类别是错误映射,因为 SPI 抛出的异常与 NPGSQL 不同。这些不兼容性虽然是细微的但数量众多;我们将继续努力改进它们。

以下是我们当前已测试的 SPI 操作:

  • 数据操作语言 (DML) 操作
    • Select
    • Insert
    • Update
    • Delete
  • 数据定义语言 (DDL) 操作
    • Create Table
    • Alter Table
    • Drop Table
    • Truncate
    • Create Index
    • Drop Index
    • Create View
    • Drop View
    • Create Function
    • Call Function
    • Drop Function
    • Create Procedure
    • Call Procedure
    • Drop Procedure
  • 事务控制
    • Begin Transaction
    • Commit
    • Rollback
  • 支持的数据类型:所有 pl/dotnet 类型
    • 基本类型(包括范围)
    • 数组类型
    • Record

我们尚未支持的功能

我们缺乏对 multirange、enum 和 composite/table 类型的支持。我们打算添加它们。

我们的 SPI 实现缺少一些小功能,例如子事务,并且我们有时抛出错误的**方式**与 NPGSQL 不同(因此略有不兼容)。

我们的构建系统(包括 dpkg 和二进制输出)是可用的,但不如我们期望的那样整洁。

我们欢迎代码提交来解决这些问题中的任何一个,并希望随着时间的推移改进它们。

在哪里获取

我们的操作系统支持

  • 我们完全支持 Linux,并为 Debian 和 Ubuntu 提供 dpkg。 (详情请参阅我们的 安装页面
  • 我们已在 OSX(arm 和 x86)上构建并测试了该系统,但尚未进行打包。
  • 我们期待很快推出 Windows 支持;如果您想帮忙,请联系我们。

如何联系我们

我们欢迎社区的声音。您可以通过我们的 GitHub 讨论论坛 联系我们,或发送电子邮件至 pldotnet@brickabode.com