1 /*Copyright (c) Brian B.
3 This library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Lesser General Public
5 License as published by the Free Software Foundation; either
6 version 3 of the License, or (at your option) any later version.
7 See the file LICENSE included with this distribution for more
16 #include <netinet/in.h>
20 #include <libex/str.h>
21 #include <libex/time.h>
22 #include <libex/endian.h>
25 #define NUMERIC_POS 0x0000
26 #define NUMERIC_NEG 0x4000
27 #define NUMERIC_SHORT 0x8000
28 #define NUMERIC_NAN 0xC000
29 #define NUMERIC_DSCALE_MASK 0x3FFF
31 typedef struct in_addr inet_t
;
32 typedef int32_t date_t
;
33 typedef int32_t fsec_t
;
65 int timestamp_to_tm (tm_t dt
, struct tm
*tm
);
66 struct tm
*date_to_tm (date_t dt
, struct tm
*tm
);
67 struct tm
*interval_to_tm(pg_intv_t
*span
, struct tm
*tm
);
68 int tm_to_timestamp (struct tm
*tm
, fsec_t fsec
, int *tzp
, tm_t
*result
);
69 date_t
tm_to_date (struct tm
*tm
);
71 double pg_conv_double (double d
);
72 float pg_conv_float (float f
);
75 void pg_get_numeric (uint8_t *buf
, mpq_t res
, uint16_t *scale
);
76 str_t
*pg_numstr (mpq_ptr x
, int base
, uint16_t dscale
, int float_prec
);
79 typedef struct pgfld pgfld_t
;
88 typedef pgfld_t
* pgfld_ptr_t
;
90 #define PG_DEF_MPZ { ._mp_alloc = 0, ._mp_size = 0, ._mp_d = NULL }
91 #define PG_DEF_MPQ { ._mp_num = PG_DEF_MPZ, ._mp_den = PG_DEF_MPZ }
92 #define PG_DEF_NUMERIC_DATA { .q = {PG_DEF_MPQ} }
94 #define PG_DEF { .is_null = 1, .oid = 0, .fmt = 0 }
95 #define PG_DEF_SMALL { .is_null = 1, .oid = OID_INT2, .fmt = 1 }
96 #define PG_DEF_INT { .is_null = 1, .oid = OID_INT4, .fmt = 1 }
97 #define PG_DEF_BIGINT { .is_null = 1, .oid = OID_INT8, .fmt = 1 }
98 #define PG_DEF_FLOAT { .is_null = 1, .oid = OID_FLOAT4, .fmt = 1 }
99 #define PG_DEF_DOUBLE { .is_null = 1, .oid = OID_FLOAT8, .fmt = 1 }
100 #define PG_DEF_VARCHAR { .is_null = 1, .oid = OID_VARCHAR, .fmt = 0 }
101 #define PG_DEF_CHAR { .is_null = 1, .oid = OID_CHAR, .fmt = 0 }
102 #define PG_DEF_BOOL { .is_null = 1, .oid = OID_BOOL, .fmt = 1 }
103 #define PG_DEF_DATE { .is_null = 1, .oid = OID_DATE, .fmt = 1 }
104 #define PG_DEF_TIMESTAMP { .is_null = 1, .oid = OID_TIMESTAMP, .fmt = 1 }
105 #define PG_DEF_UUID { .is_null = 1, .oid = OID_UUID, .fmt = 1 }
106 #define PG_DEF_BYTEA { .is_null = 1, .oid = OID_BYTEA, .fmt = 1 }
107 #define PG_DEF_BIT32 { .is_null = 1, .oid = OID_BIT, .fmt = 1 }
108 #define PG_DEF_MONEY { .is_null = 1, .oid = OID_MONEY, .fmt = 1 }
109 #define PG_DEF_TEXT { .is_null = 1, .oid = OID_TEXT, .fmt = 0 }
111 #define PG_SET(X,V,L) X.is_null = 0; X.data.s = V, X.len = 0 == L ? strlen(V) : L
112 #define PG_SET_NULL(X) X.is_null = 1
113 #define PG_SET_SMALL(X,V) X.is_null = 0, X.data.i2 = htobe16(V), X.len = sizeof(int16_t)
114 #define PG_SET_INT(X,V) X.is_null = 0; X.data.i4 = htobe32(V), X.len = sizeof(int32_t)
115 #define PG_SET_BIGINT(X,V) X.is_null = 0; X.data.i8 = htobe64(V), X.len = sizeof(int64_t)
116 #define PG_SET_FLOAT(X,V) X.is_null = 0; X.data.f4 = pg_conv_float(V), X.len = sizeof(float)
117 #define PG_SET_DOUBLE(X,V) X.is_null = 0; X.data.f8 = pg_conv_double(V), X.len = sizeof(double)
118 #define PG_SET_VARCHAR(X,V,L) X.is_null = 0; X.data.s = V, X.len = 0 == L ? strlen(V) : L
119 #define PG_SET_CHAR(X,V,L) X.is_null = 0; X.data.s = V, X.len = 0 == L ? strlen(V) : L
120 #define PG_SET_BOOL(X,V) X.is_null = 0; X.data.b = V ? 1 : 0, X.len = sizeof(int8_t)
121 #define PG_SET_DATE(X,V) X.is_null = 0; X.data.d = htobe32(V), X.len = sizeof(date_t)
122 #define PG_SET_TIMESTAMP(X,V) X.is_null = 0; X.data.tm = htobe64(V), X.len = sizeof(tm_t)
123 #define PG_SET_BYTEA(X,V,L) X.is_null = 0; X.data.s = V; X.len = L
124 #define PG_SET_UUID(X,V) X.is_null = 0; X.data.u = V, X.len = sizeof(uuid_t)
125 #define PG_SET_BIT32(X,V) X.is_null = 0, X.data.bit32.bit = htobe32(V), X.data.bit32.len = htobe32(32), X.len = sizeof(pg_bit32_t)
126 #define PG_SET_TEXT(X,V,L) X.is_null = 0; X.data.s = V, X.len = 0 == L ? strlen(V) : L
127 #define PG_SET_MONEY(X,V) PG_SET_BIGINT(X,V)
129 #define PG_INIT(V,L) { .is_null = 0, .oid = 0, .fmt = 0, .data.s = V, .len = 0 == L ? strlen(V) : L }
130 #define PG_INIT_NULL { .is_null = 1, .oid = 0, .fmt = 0 }
131 #define PG_INIT_SMALL(V) { .is_null = 0, .oid = OID_INT2, .fmt = 1, .data.i2 = htobe16(V), .len = sizeof(int16_t) }
132 #define PG_INIT_INT(V) { .is_null = 0, .oid = OID_INT4, .fmt = 1, .data.i4 = htobe32(V), .len = sizeof(int32_t) }
133 #define PG_INIT_BIGINT(V) { .is_null = 0, .oid = OID_INT8, .fmt = 1, .data.i8 = htobe64(V), .len = sizeof(int64_t) }
134 #define PG_INIT_FLOAT(V) { .is_null = 0, .oid = OID_FLOAT4, .fmt = 1, .data.f4 = pg_conv_float(V), .len = sizeof(float) }
135 #define PG_INIT_DOUBLE(V) { .is_null = 0, .oid = OID_FLOAT8, .fmt = 1, .data.f8 = pg_conv_double(V), .len = sizeof(double) }
136 #define PG_INIT_VARCHAR(V,L) { .is_null = 0, .oid = OID_VARCHAR, .fmt = 0, .data.s = V, .len = 0 == L ? strlen(V) : L }
137 #define PG_INIT_CHAR(V,L) { .is_null = 0, .oid = OID_CHAR, .fmt = 0, .data.s = V, .len = 0 == L ? strlen(V) : L }
138 #define PG_INIT_BOOL(V) { .is_null = 0, .oid = OID_BOOL, .fmt = 1, .data.b = V ? 1 : 0, .len = sizeof(int8_t) }
139 #define PG_INIT_DATE(V), { .is_null = 0, .oid = OID_DATE, .fmt = 1, .data.s = htobe32(V), .len = sizeof(date_t) }
140 #define PG_INIT_TIMESTAMP(V) { .is_null = 0, .oid = OID_TIMESTAMP, .fmt = 1, .data.tm = htobe64(V), .len = sizeof(int64_t) }
141 #define PG_INIT_BYTEA(V) { .is_null = 0, .oid = OID_BYTEA, .fmt = 1, .data.s = V, .len = L }
142 #define PG_INIT_UUID(V) { .is_null = 0, .oid = OID_UUID, .fmt = 1, .data.u = V, .len = sizeof(uuid_t) }
143 #define PG_INIT_BIT32(V) { .is_null = 0, .oid = OID_BIT, .fmt = 1, .data.bit32.bit = htobe32(V), .data.bit32.len = htobe32(32), .len = sizeof(pg_bit32_t) }
144 #define PG_INIT_TEXT(V,L) { .is_null = 0, .oid = OID_TEXT, .fmt = 0, .data.s = V, .len = 0 == L ? strlen(V) : L }
145 #define PG_INIT_MONEY(V) { .is_null = 0, .oid = OID_MONEY, .fmt = 1, .data.i8 = htobe64(V), .len = sizeof(int64_t) }