pgtypes: Support uuid and xid8

This commit is contained in:
Yorhel 2025-02-10 11:41:20 +01:00
parent 7076714296
commit 7515032261
2 changed files with 60 additions and 5 deletions

View file

@ -112,6 +112,16 @@ SENDFN(uint4) {
fustr_writebeU(32, out, iv);
}
RECVFN(uint8) {
RLEN(8);
return newSVuv(fu_frombeU(64, buf));
}
SENDFN(uint8) {
/* Doesn't have the nice input validation of 'SIV', but this type is pretty rare anyway */
fustr_writebeU(64, out, SvUV(val));
}
RECVFN(bytea) {
return newSVpvn(buf, len);
}
@ -375,6 +385,43 @@ SENDFN(inet) {
}
}
RECVFN(uuid) {
RLEN(16);
char tmp[64];
char *out = tmp;
unsigned char *in = (unsigned char *)buf;
int i;
for (i=0; i<16; i++) {
if (i == 4 || i == 6 || i == 8 || i == 10) *out++ = '-';
*out++ = PL_hexdigit[(in[i] >> 4) & 0x0f];
*out++ = PL_hexdigit[in[i] & 0x0f];
}
*out = '\0';
return newSVpv(tmp, 0);
}
SENDFN(uuid) {
const char *in = SvPV_nolen(val);
int bytes = 0;
unsigned char dig = 0x10;
if (*in == '{') in++;
for (; *in; in++) {
if (*in == '}') break;
if (dig == 0x10 && *in == '-') continue;
unsigned char x = *in;
x = x >= '0' && x <= '9' ? x-'0' : x >= 'A' && x <= 'F' ? x-'A'+10 : x >= 'a' && x <= 'f' ? x-'a'+10 : 0x10;
if (x == 0x10) SERR("invalid UUID");
if (bytes >= 16) SERR("invalid UUID");
if (dig == 0x10) dig = x;
else {
fustr_write_ch(out, (dig << 4) + x);
bytes++;
dig = 0x10;
}
}
if (dig != 0x10 || bytes != 16) SERR("invalid UUID");
}
#undef SIV
#undef RLEN
#undef RECVFN
@ -508,10 +555,10 @@ SENDFN(inet) {
A( 2210, "_regclass", 2205 )\
A( 2211, "_regtype", 2206 )\
A( 2949, "_txid_snapshot", 2970 )\
/* 2950 uuid */\
B( 2950, "uuid", uuid )\
A( 2951, "_uuid", 2950 )\
/* 2970 txid_snapshot */\
/* 3220 pg_lsn */\
/* 2970 txid_snapshot: same as pg_snapshot */\
/* 3220 pg_lsn: uint64 with custom formatting */\
A( 3221, "_pg_lsn", 3220 )\
/* 3361 pg_ndistinct */\
/* 3402 pg_dependencies */\
@ -538,9 +585,9 @@ SENDFN(inet) {
/* 4600 pg_brin_bloom_summary */\
/* 4601 pg_brin_minmax_multi_summary */\
/* 5017 pg_mcv_list */\
/* 5038 pg_snapshot */\
/* 5038 pg_snapshot: int4 nxip, int8 xmin, int8 xmax, int8 xip */\
A( 5039, "_pg_snapshot", 5038 )\
/* 5069 xid8 */
B( 5069, "xid8", uint8 )
static const fupg_type fupg_builtin[] = {
#define B(oid, name, fun) { oid, 0, name"\0", fupg_send_##fun, fupg_recv_##fun },

View file

@ -57,6 +57,8 @@ for my $t (qw/regproc oid xid cid regprocedure regoper regoperator regtype regco
}
v regtype => 17, undef, 'bytea'; # like this
v xid8 => 18446744073709551615;
v bytea => '', undef, '\x';
v bytea => 'hello', undef, '\x68656c6c6f';
v bytea => "\xaf\x90", undef, '\xaf90';
@ -99,6 +101,12 @@ v cidr => '0.0.0.0', '0.0.0.0/32', undef, '0.0.0.0/32';
v cidr => '::', '::/128', undef, '::/128';
f inet => $_ for ('', [], '0.0.0.0/a', '0.0.0.0/1a', '[::]', '0.0.0.0/33', '::/129', '/1', ':/1');
v uuid => 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11';
v uuid => '{A0EEBC99-9C0B4EF8BB6D6BB9BD38-0A11}', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', '{A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11}', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11';
f uuid => 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a111';
f uuid => 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a1';
f uuid => 'a0egbc99-9c0b-4ef8-bb6d-6bb9bd380a11';
v 'int[]', [], undef, '{}';
v 'int[]', [1], undef, '{1}';
v 'int[]', [1,-3,undef,3], undef, '{1,-3,NULL,3}';