BIT VARYING data type support added
BIT and BIT VARYING ("varbit") data types have the same binary format
so we can just use for them the same C representation and the code of handlers.
This commit is contained in:
@@ -115,7 +115,9 @@ static PGtypeHandler pg_handlers[] = {
|
||||
|
||||
/* bit string types */
|
||||
{34, "pg_catalog", "bit", -1, ZPBITOID, 1561, pqt_put_bit,
|
||||
pqt_get_bit, __HANDLER_DEFAULTS__}
|
||||
pqt_get_bit, __HANDLER_DEFAULTS__},
|
||||
{35, "pg_catalog", "varbit", -1, VARBITOID, 1563, pqt_put_varbit,
|
||||
pqt_get_varbit, __HANDLER_DEFAULTS__}
|
||||
};
|
||||
|
||||
static int
|
||||
|
||||
@@ -255,7 +255,7 @@ extern "C" {
|
||||
#define NAMEOID 19
|
||||
#define TEXTOID 25
|
||||
#define ZPBITOID 1560
|
||||
#define VARBITOID 1562 /* not supported yet */
|
||||
#define VARBITOID 1562
|
||||
#define BYTEAOID 17
|
||||
/* date and time types */
|
||||
#define DATEOID 1082
|
||||
@@ -526,6 +526,8 @@ int pqt_put_bytea(PGtypeArgs *args);
|
||||
int pqt_get_bytea(PGtypeArgs *args);
|
||||
int pqt_put_bit(PGtypeArgs *args);
|
||||
int pqt_get_bit(PGtypeArgs *args);
|
||||
int pqt_put_varbit(PGtypeArgs *args);
|
||||
int pqt_get_varbit(PGtypeArgs *args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -146,7 +146,9 @@ typedef struct
|
||||
int len_bytes;
|
||||
int32_t len_bits;
|
||||
char *data;
|
||||
} PGbit;
|
||||
} PGvarbit;
|
||||
|
||||
typedef PGvarbit PGbit;
|
||||
|
||||
/* ----------------
|
||||
* Numeric types
|
||||
|
||||
@@ -842,15 +842,16 @@ static void test_varlen(int format)
|
||||
"-62731893541288039212143296120112.12431212671229121291821928918211";
|
||||
static char bitdata[] = {7, 6, 5, 4, 3, 2, 1, 0};
|
||||
PGbit bit;
|
||||
PGbit bitin = {8, 59, bitdata};
|
||||
PGvarbit varbit;
|
||||
PGvarbit varbitin = {8, 59, bitdata};
|
||||
|
||||
PQparamReset(param);
|
||||
printf("\nVariable-length types: (%s)\n", format ? "binary" : "text");
|
||||
|
||||
r = PQputf(param, "%bpchar %bpchar* %varchar %varchar* "
|
||||
"%text %text* %bytea %bytea* %uuid %numeric %bit",
|
||||
"%text %text* %bytea %bytea* %uuid %numeric %bit %varbit",
|
||||
bpcharin, bpcharin, varcharin, varcharin, textin, textin,
|
||||
&byteain, &byteain, uuidin, numin, &bitin);
|
||||
&byteain, &byteain, uuidin, numin, &varbitin, &varbitin);
|
||||
PUTOKAY(param, r, "PQputf(varlen)");
|
||||
|
||||
DROP_TABLE("libpq_varlen");
|
||||
@@ -858,28 +859,29 @@ static void test_varlen(int format)
|
||||
result = PQexec(conn, "CREATE TABLE libpq_varlen ("
|
||||
"bp_a bpchar(32), bp_b bpchar(32), vc_a varchar(32), vc_b varchar(32), "
|
||||
"text_a text, text_b text, bytea_a bytea, bytea_b bytea, "
|
||||
"uid uuid, n numeric, bit_a bit(59))");
|
||||
"uid uuid, n numeric, bit_a bit(59), varbit_a bit varying(62))");
|
||||
CMDOKAY("creating libpq_varlen table");
|
||||
PQclear(result);
|
||||
|
||||
result = PQparamExec(conn, param, "INSERT INTO libpq_varlen VALUES"
|
||||
"($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)", format);
|
||||
"($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)", format);
|
||||
CMDOKAY("PQparamExec(INSERT:varlen)");
|
||||
PQclear(result);
|
||||
|
||||
result = PQparamExec(conn, NULL,
|
||||
"SELECT bp_a,vc_a,text_a,bytea_a,uid,n,bit_a FROM libpq_varlen", format);
|
||||
"SELECT bp_a,vc_a,text_a,bytea_a,uid,n,bit_a,varbit_a FROM libpq_varlen", format);
|
||||
TUPSOKAY("PQparamExec(SELECT:varlen)");
|
||||
|
||||
r = PQgetf(result, 0,
|
||||
"%bpchar %varchar %text %bytea %uuid %numeric %bit",
|
||||
"%bpchar %varchar %text %bytea %uuid %numeric %bit %varbit",
|
||||
0, &bpcharp, /* field_num, PGbpchar* */
|
||||
1, &varcharp, /* field_num, PGvarchar* */
|
||||
2, &textp, /* field_num, PGtext* */
|
||||
3, &byteap, /* field_num, PGbytea* */
|
||||
4, &uuid, /* field_num, PGuuid* */
|
||||
5, &num, /* field_num, PGnumeric* */
|
||||
6, &bit); /* field num, PGbit* */
|
||||
6, &bit, /* field num, PGbit* */
|
||||
7, &varbit); /* field num, PGvarbit* */
|
||||
GETOKAY(r, "PQgetf(varlen)");
|
||||
|
||||
/* Because we are using the '*' specifier flag, we clear the results at
|
||||
@@ -920,9 +922,9 @@ static void test_varlen(int format)
|
||||
CHKVLEN("numeric", num, numin);
|
||||
|
||||
testcnt++;
|
||||
if (bitin.len_bytes != bit.len_bytes ||
|
||||
bitin.len_bits != bit.len_bits ||
|
||||
memcmp(bitin.data, bit.data, (size_t)bit.len_bytes))
|
||||
if (varbitin.len_bytes != bit.len_bytes ||
|
||||
varbitin.len_bits != bit.len_bits ||
|
||||
memcmp(varbitin.data, bit.data, (size_t)bit.len_bytes))
|
||||
{
|
||||
failcnt++;
|
||||
fprintf(stderr, " %%bit - FAILED'n");
|
||||
@@ -930,6 +932,17 @@ static void test_varlen(int format)
|
||||
else
|
||||
printf(" %%bit - passed\n");
|
||||
|
||||
testcnt++;
|
||||
if (varbitin.len_bytes != varbit.len_bytes ||
|
||||
varbitin.len_bits != varbit.len_bits ||
|
||||
memcmp(varbitin.data, varbit.data, (size_t)varbit.len_bytes))
|
||||
{
|
||||
failcnt++;
|
||||
fprintf(stderr, " %%varbit - FAILED'n");
|
||||
}
|
||||
else
|
||||
printf(" %%varbit - passed\n");
|
||||
|
||||
PQclear(result);
|
||||
}
|
||||
|
||||
|
||||
+29
-15
@@ -84,31 +84,33 @@ pqt_get_bytea(PGtypeArgs *args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Bit string types */
|
||||
|
||||
int
|
||||
pqt_put_bit(PGtypeArgs *args)
|
||||
pqt_put_varbit(PGtypeArgs *args)
|
||||
{
|
||||
int len_bytes;
|
||||
int total_bytes;
|
||||
char *out;
|
||||
PGbit *bit = va_arg(args->ap, PGbit *);
|
||||
PUTNULLCHK(args, bit);
|
||||
len_bytes = bit->len_bytes;
|
||||
PGvarbit *varbit = va_arg(args->ap, PGvarbit *);
|
||||
PUTNULLCHK(args, varbit);
|
||||
len_bytes = varbit->len_bytes;
|
||||
total_bytes = len_bytes + (int)sizeof(int32_t);
|
||||
if (args->put.expandBuffer(args, total_bytes) == -1)
|
||||
RERR_MEM(args);
|
||||
out = args->put.out;
|
||||
pqt_buf_putint4(out, bit->len_bits);
|
||||
memcpy(out + sizeof(int32_t), bit->data, (size_t)len_bytes);
|
||||
pqt_buf_putint4(out, varbit->len_bits);
|
||||
memcpy(out + sizeof(int32_t), varbit->data, (size_t)len_bytes);
|
||||
return total_bytes;
|
||||
}
|
||||
|
||||
int
|
||||
pqt_get_bit(PGtypeArgs *args)
|
||||
pqt_get_varbit(PGtypeArgs *args)
|
||||
{
|
||||
DECLVALUE(args);
|
||||
DECLLENGTH(args);
|
||||
PGbit *bit = va_arg(args->ap, PGbit *);
|
||||
CHKGETVALS(args, bit);
|
||||
PGvarbit *varbit = va_arg(args->ap, PGvarbit *);
|
||||
CHKGETVALS(args, varbit);
|
||||
if (args->format == TEXTFMT)
|
||||
{
|
||||
unsigned char *cur_byte;
|
||||
@@ -139,14 +141,26 @@ pqt_get_bit(PGtypeArgs *args)
|
||||
mask_byte = 0x80;
|
||||
}
|
||||
}
|
||||
bit->len_bytes = len_bytes;
|
||||
bit->len_bits = (int32_t)len_bits;
|
||||
bit->data = data;
|
||||
varbit->len_bytes = len_bytes;
|
||||
varbit->len_bits = (int32_t)len_bits;
|
||||
varbit->data = data;
|
||||
return 0;
|
||||
}
|
||||
/* binary format */
|
||||
bit->len_bytes = valuel - (int)sizeof(int32_t);
|
||||
bit->len_bits = pqt_buf_getint4(value);
|
||||
bit->data = value + sizeof(int32_t);
|
||||
varbit->len_bytes = valuel - (int)sizeof(int32_t);
|
||||
varbit->len_bits = pqt_buf_getint4(value);
|
||||
varbit->data = value + sizeof(int32_t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pqt_put_bit(PGtypeArgs *args)
|
||||
{
|
||||
return pqt_put_varbit(args);
|
||||
}
|
||||
|
||||
int
|
||||
pqt_get_bit(PGtypeArgs *args)
|
||||
{
|
||||
return pqt_get_varbit(args);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user