https://pldotnet.brickabode.com
460
PL/.NET (or simply pldotnet) adds full support for C# and F# to PostgreSQL. See more at: https://pldotnet.brickabode.com/
Our white paper has extensive discussion of all of these items; check it out.
To get started with PL/.NET, you will need to install it on your PostgreSQL server or run it with a Docker container. You can find more information in our Installation Guide.
Detailed installation and usage instructions can also be found in the pldotnet Wiki pages, along with examples and information on the supported PostgreSQL data types.
Feel free to open an issue or a discussion topic on our GitHub repository.
We provide ready-to-use Docker images to make running PL/.NET fast and simple. Two variants are available:
brickabode/pldotnet:latest – Lean and production-ready image.brickabode/pldotnet:dev – Development image with testing tools and examples.Example: pull and start the development image for quick experimentation:
docker pull brickabode/pldotnet:dev
docker run --rm -it \
--name pldotnet-test \
-p 5432:5432 \
brickabode/pldotnet:dev bash
Use latest in production deployments, and dev when you want a fully equipped environment for building, testing, or exploring PL/.NET features.
Here is an example that returns a set of records in C#:
CREATE OR REPLACE FUNCTION dynamic_record_generator_srf(lim INT8)
RETURNS SETOF record
AS $$
var upperLimit = lim.HasValue ? lim : System.Int32.MaxValue;
for(long i=0;i<upperLimit;i++){ yield return new object?[] { i, $"Number is {i}" }; }
$$ LANGUAGE plcsharp;
select * from dynamic_record_generator_srf(10) as record(a int8, b text);
The same example in F#:
CREATE OR REPLACE FUNCTION dynamic_record_generator_srf_fsharp(lim INT8)
RETURNS SETOF record
AS $$
let upperLimit = if lim.HasValue then lim.Value else int64 System.Int32.MaxValue
seq { for i in 0L .. upperLimit - 1L do yield [| box i; $"Number is {i}" |] }
$$ LANGUAGE plfsharp;
select * from dynamic_record_generator_srf_fsharp(10) as record(a int8, b text);
The tests/ folder has a complete suite of unit tests in both C# and F#; we
encourage you to consult it for examples of SQL code for your favorite
datatype or SQL feature.
We support all SQL function modes:
Data types and SPI are described below.
We support 36 PostgreSQL types, with all mapped to their NPGSQL-standard dotnet types. The only notable exceptions are multirange, enum, and struct types, all of which we hope to add in the future. All datatypes are nullable, have full array support, and are fully unit-tested for C# and F#.
| PostgreSQL type | Dotnet type |
|---|---|
| BitString | BitArray |
| Bool | bool |
| Box | NpgsqlBox |
| Bytea | byte[] |
| Cidr | (IPAddress Address, int Netmask) |
| Circle | NpgsqlCircle |
| Date | DateOnly |
| DateRange | DateOnly, DateHandler |
| Double | double |
| Float | float |
| Inet | (IPAddress Address, int Netmask) |
| Interval | NpgsqlInterval |
| Int | int |
| IntRange | int, IntHandler |
| Json | string |
| Line | NpgsqlLine |
| LineSegment | NpgsqlLSeg |
| Long | long |
| LongRange | long, LongHandler |
| Macaddr8 | PhysicalAddress |
| Macaddr | PhysicalAddress |
| Money | decimal |
| Path | NpgsqlPath |
| Point | NpgsqlPoint |
| Polygon | NpgsqlPolygon |
| Record | object[] |
| Short | short |
| String | string |
| Timestamp | DateTime |
| TimestampRange | DateTime, TimestampHandler |
| TimestampTz | DateTime |
| TimestampTzRange | DateTime, TimestampTzHandler |
| Time | TimeOnly |
| TimeTz | DateTimeOffset |
| Uuid | Guid |
| VarBitString | BitArray |
Our SPI leverages the NPGSQL client library to provide a native dotnet implementation, making it maximally compatible with existing client code. We intercepted the NPGSQL calls at a very low level to replace the client protocol handling with SPI calls; NPGSQL was otherwise unmodified. We imported the NPGSQL test suite as stored procedures and are using it for our testing, giving us high confidence in our compatibility.
Work remains to improve the compatibility and add features. Our biggest category of NPGSQL incompatibility is error mapping, because SPI throws exceptions differently than NPGSQL does. Such incompatibilities are minor, and work continues to improve them.
Here are our currently tested SPI operations:
We lack support for multirange, enum, and composite/table types.
Our SPI implementation lacks some minor features like sub-transactions.
We fully support Linux and provide dpkg's for Debian and Ubuntu, but we do not yet have packaging on Windows or OS/X.
Our package build system for dpkg is functional but not as tidy as we would like.
We welcome code submissions to address any of these features, and we hope to improve them all in time.
Content type
Image
Digest
sha256:3b6909d5f…
Size
473 MB
Last updated
about 1 year ago
docker pull brickabode/pldotnet