PostgreSQL
Supported data types
What each .NET type is stored as in PostgreSQL, and what each PostgreSQL type reads back as.
Writing: .NET to the database
The values Create and Update accept, and what each column stores.
| .NET value | Column | Stored as |
|---|---|---|
string |
text, varchar(n), char(n) |
as written (char(n) pads with spaces) |
short / int / long |
smallint / int / bigint |
32000 / 2000000000 / 9000000000000 |
decimal |
numeric(p, s) |
12345.678901 |
float / double |
real / double precision |
3.25 / 2.718281828459045 |
bool |
boolean |
true |
Guid |
uuid |
6f9619ff-8b86-d011-b42d-00c04fc964ff |
DateTime (Kind Utc), DateTimeOffset |
timestamptz |
the UTC instant: 2026-11-07 14:30:00+00 |
DateTime (Kind Unspecified) |
timestamp |
as written: 2026-11-07 09:00:00 |
DateOnly / TimeOnly / TimeSpan |
date / time / interval |
2026-11-07 / 17:45:30 / 1 day 12:30:00 |
byte[], ArxBytea |
bytea |
\xcafe |
ArxJsonB |
jsonb |
the JSON |
string[], int[], decimal[], Guid[], DateOnly[], DateTime[], … |
text[], int[], … |
{red,green}, {1,2,3}, … |
ArxEntityReference |
the lookup column | the referenced id |
ArxSelectionSetValue |
the set's column | the option's code |
null |
any | NULL |
byte, sbyte / ushort / uint / ulong |
converted to smallint / int / bigint / numeric |
200 / 65000 / 4000000000 / 18446744073709551615 |
char |
text | X |
a plain enum |
refused (ARX1007) | write (int)value or value.ToString(), or use a selection set, which stores the code its set declares |
DateTime with Kind Local |
timestamptz |
converted to UTC |
Any other type is refused before anything is sent (ARX1007 UnsupportedValueType): write uri.ToString() rather than
a Uri. RealCase2_EveryDataType writes every row of this table and prints what PostgreSQL stored.
With the column types preloaded (ArxPreLoadMode.DataTypes), a number with a fraction written to a whole-number column is refused before PostgreSQL (ARX4001 ValueOutOfRange) on a create, an update and a write by a filter, where PostgreSQL would round it (7.9 stored as 8); a condition in a read (qty < 7.5) isn't refused. A NaN or an infinity written to a declared decimal column is refused the same way. Without declared types, PostgreSQL stores a double NaN in a numeric column, and it reads back as a double.
Dates and times
| You have | Use | Column |
|---|---|---|
| A moment (an order was placed) | DateTimeOffset, or DateTime with Kind Utc |
timestamptz |
| A wall-clock time with no zone | DateTime with Kind Unspecified |
timestamp |
| A calendar date | DateOnly |
date |
| A time of day | TimeOnly |
time |
| A duration | TimeSpan |
interval |
The same moment written as a DateTimeOffset (+08:00), a UTC DateTime or a local DateTime is stored as the same
instant. A DateTime with Kind Unspecified written to a timestamptz column is read in the session's time zone:
ARX's own connections are UTC (Timezone=UTC), so 09:00 is stored as 09:00+00; a connection string that names
another zone (Timezone=Asia/Manila) makes it 01:00+00. Give a moment Kind Utc, or a DateTimeOffset, so the
session can't change it. Refused: default(DateTime) (ARX1013: it means "not set", and PostgreSQL would store -infinity; use
null), and a date given as a string (ARX4004: ARX never parses strings as dates). Full rules:
Data types.
Reading: the database to .NET
What Retrieve and RetrieveMultiple give back for each column.
| PostgreSQL column | Reads back as | Notes |
|---|---|---|
text, varchar(n), char(n) |
string |
char(n) keeps its padding spaces; "" stays "" |
smallint / integer / bigint |
short / int / long |
|
numeric(p, s) |
decimal |
More than 28 significant digits: ARX4001 ValueOutOfRange. NaN, Infinity and -Infinity, which a numeric can hold and a decimal can't, read back as a double (from 0.1.0-preview.5; the read failed before) |
real / double precision |
float / double |
|
boolean |
bool |
|
uuid |
Guid |
|
timestamptz |
DateTime, Kind Utc |
The instant, in UTC whatever the session's time zone |
timestamp |
DateTime, Kind Unspecified |
The wall-clock time as stored |
date / time / interval |
DateOnly / TimeOnly / TimeSpan |
An interval with months or years: ARX4004 DataTypeMismatch (a TimeSpan can't hold one) |
bytea |
byte[] |
|
json, jsonb |
ArxJsonB |
SerializedValue holds the JSON text |
An array (text[], int[], date[], …) |
T[] (string[], int[], DateOnly[], …) |
With NULL elements, a value type reads as T?[] (int?[]) |
| An enum type | string |
Its label, from the first read when the schema is preloaded |
| A composite type | string |
Its text form |
| A domain | Its base type | |
A declared lookup (.Lookup(...)) |
ArxEntityReference |
Name from the referenced table's .DisplayName(...) |
| A selection set column | Its stored code | entity.GetSelectionSet(column, set, catalog) gives the option |
| NULL | null |
The attribute is present, with a null value |
RealCase1_EveryDataTypeReadBack writes one row of every type with Create and prints each value's .NET type as it
reads back.