pg: Add dynamic type loading & support enum types
Least efficient way to support enums, really. *shrug*
This commit is contained in:
parent
2aaec6a218
commit
7b76d94719
5 changed files with 114 additions and 29 deletions
31
c/pgtypes.c
31
c/pgtypes.c
|
|
@ -24,10 +24,10 @@ struct fupg_recv {
|
|||
|
||||
typedef struct {
|
||||
Oid oid;
|
||||
char name[16]; /* Postgres has a 64 byte limit on names, but this is sufficient for the core types listed here */
|
||||
char name[64];
|
||||
fupg_send_fn send;
|
||||
fupg_recv_fn recv;
|
||||
} fupg_core_type;
|
||||
} fupg_type;
|
||||
|
||||
|
||||
|
||||
|
|
@ -132,9 +132,10 @@ SENDFN(char) {
|
|||
fustr_write(out, buf, len);
|
||||
}
|
||||
|
||||
/* Works for many text-based column types.
|
||||
* Assumes client_encoding=utf8, will create a mess otherwise */
|
||||
/* Works for many text-based column types, including receiving any value in the text format */
|
||||
RECVFN(text) {
|
||||
if (!is_c9strict_utf8_string((const U8*)buf, len))
|
||||
fu_confess("Received invalid UTF-8 for type '%s' (oid %u)", ctx->name, ctx->oid);
|
||||
return newSVpvn_utf8(buf, len, 1);
|
||||
}
|
||||
|
||||
|
|
@ -248,7 +249,7 @@ SENDFN(jsonpath) {
|
|||
|
||||
Ordered by oid to support binary search.
|
||||
(name is only used when formatting error messages, for now) */
|
||||
#define CORETYPES \
|
||||
#define BUILTINS \
|
||||
B( 16, "bool", bool )\
|
||||
B( 17, "bytea", bytea )\
|
||||
B( 18, "char", char )\
|
||||
|
|
@ -320,24 +321,28 @@ SENDFN(jsonpath) {
|
|||
/* 5038 pg_snapshot */\
|
||||
/* 5069 xid8 */
|
||||
|
||||
static const fupg_core_type fupg_core_types[] = {
|
||||
static const fupg_type fupg_builtin[] = {
|
||||
#define B(oid, name, fun) { oid, name"\0", fupg_send_##fun, fupg_recv_##fun },
|
||||
CORETYPES
|
||||
BUILTINS
|
||||
#undef B
|
||||
};
|
||||
|
||||
#undef CORETYPES
|
||||
#undef BUILTINS
|
||||
|
||||
#define FUPG_CORE_TYPES (sizeof(fupg_core_types) / sizeof(fupg_core_type))
|
||||
#define FUPG_BUILTIN (sizeof(fupg_builtin) / sizeof(fupg_type))
|
||||
|
||||
|
||||
static const fupg_core_type *fupg_core_type_byoid(Oid oid) {
|
||||
int i, b = 0, e = FUPG_CORE_TYPES-1;
|
||||
static const fupg_type *fupg_type_byoid(const fupg_type *list, int len, Oid oid) {
|
||||
int i, b = 0, e = len-1;
|
||||
while (b <= e) {
|
||||
i = b + (e - b)/2;
|
||||
if (fupg_core_types[i].oid == oid) return fupg_core_types+i;
|
||||
if (fupg_core_types[i].oid < oid) b = i+1;
|
||||
if (list[i].oid == oid) return list+i;
|
||||
if (list[i].oid < oid) b = i+1;
|
||||
else e = i-1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const fupg_type *fupg_builtin_byoid(Oid oid) {
|
||||
return fupg_type_byoid(fupg_builtin, FUPG_BUILTIN, oid);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue