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 },