BIT data type support added
BIT data type support has been added and a minor fix in a test of geometric types has been made.
This commit is contained in:
@@ -111,7 +111,11 @@ static PGtypeHandler pg_handlers[] = {
|
||||
|
||||
/* more character types */
|
||||
{33, "pg_catalog", "name", -1, NAMEOID, 1003, pqt_put_text,
|
||||
pqt_get_text, __HANDLER_DEFAULTS__} /* supports ptr */
|
||||
pqt_get_text, __HANDLER_DEFAULTS__}, /* supports ptr */
|
||||
|
||||
/* bit string types */
|
||||
{34, "pg_catalog", "bit", -1, ZPBITOID, 1561, pqt_put_bit,
|
||||
pqt_get_bit, __HANDLER_DEFAULTS__}
|
||||
};
|
||||
|
||||
static int
|
||||
|
||||
@@ -254,7 +254,7 @@ extern "C" {
|
||||
#define VARCHAROID 1043
|
||||
#define NAMEOID 19
|
||||
#define TEXTOID 25
|
||||
#define ZPBITOID 1560 /* not supported yet */
|
||||
#define ZPBITOID 1560
|
||||
#define VARBITOID 1562 /* not supported yet */
|
||||
#define BYTEAOID 17
|
||||
/* date and time types */
|
||||
@@ -524,6 +524,8 @@ int pqt_put_text(PGtypeArgs *args); /* handles varchar, bpchar and name */
|
||||
int pqt_get_text(PGtypeArgs *args); /* handles varchar, bpchar and name */
|
||||
int pqt_put_bytea(PGtypeArgs *args);
|
||||
int pqt_get_bytea(PGtypeArgs *args);
|
||||
int pqt_put_bit(PGtypeArgs *args);
|
||||
int pqt_get_bit(PGtypeArgs *args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <libpq-fe.h>
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -140,6 +141,13 @@ typedef struct
|
||||
char *data;
|
||||
} PGbytea;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int len_bytes;
|
||||
int32_t len_bits;
|
||||
char *data;
|
||||
} PGbit;
|
||||
|
||||
/* ----------------
|
||||
* Numeric types
|
||||
* ----------------
|
||||
|
||||
@@ -806,8 +806,8 @@ static void test_geometrics(int format)
|
||||
}
|
||||
|
||||
testcnt++;
|
||||
if (polygon.npts == polygon.npts &&
|
||||
memcmp(polygon.pts, polygon.pts, polygon.npts * sizeof(PGpoint))==0)
|
||||
if (polygon.npts == polygonval.npts &&
|
||||
memcmp(polygon.pts, polygonval.pts, polygon.npts * sizeof(PGpoint))==0)
|
||||
printf(" %%polygon - passed\n");
|
||||
else
|
||||
{
|
||||
@@ -840,14 +840,17 @@ static void test_varlen(int format)
|
||||
PGnumeric num;
|
||||
PGnumeric numin =
|
||||
"-62731893541288039212143296120112.12431212671229121291821928918211";
|
||||
static char bitdata[] = {7, 6, 5, 4, 3, 2, 1, 0};
|
||||
PGbit bit;
|
||||
PGbit bitin = {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",
|
||||
"%text %text* %bytea %bytea* %uuid %numeric %bit",
|
||||
bpcharin, bpcharin, varcharin, varcharin, textin, textin,
|
||||
&byteain, &byteain, uuidin, numin);
|
||||
&byteain, &byteain, uuidin, numin, &bitin);
|
||||
PUTOKAY(param, r, "PQputf(varlen)");
|
||||
|
||||
DROP_TABLE("libpq_varlen");
|
||||
@@ -855,27 +858,28 @@ 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)");
|
||||
"uid uuid, n numeric, bit_a bit(59))");
|
||||
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)", format);
|
||||
"($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)", format);
|
||||
CMDOKAY("PQparamExec(INSERT:varlen)");
|
||||
PQclear(result);
|
||||
|
||||
result = PQparamExec(conn, NULL,
|
||||
"SELECT bp_a,vc_a,text_a,bytea_a,uid,n FROM libpq_varlen", format);
|
||||
"SELECT bp_a,vc_a,text_a,bytea_a,uid,n,bit_a FROM libpq_varlen", format);
|
||||
TUPSOKAY("PQparamExec(SELECT:varlen)");
|
||||
|
||||
r = PQgetf(result, 0,
|
||||
"%bpchar %varchar %text %bytea %uuid %numeric",
|
||||
"%bpchar %varchar %text %bytea %uuid %numeric %bit",
|
||||
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* */
|
||||
5, &num, /* field_num, PGnumeric* */
|
||||
6, &bit); /* field num, PGbit* */
|
||||
GETOKAY(r, "PQgetf(varlen)");
|
||||
|
||||
/* Because we are using the '*' specifier flag, we clear the results at
|
||||
@@ -914,6 +918,18 @@ static void test_varlen(int format)
|
||||
printf(" %%uuid - passed\n");
|
||||
|
||||
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))
|
||||
{
|
||||
failcnt++;
|
||||
fprintf(stderr, " %%bit - FAILED'n");
|
||||
}
|
||||
else
|
||||
printf(" %%bit - passed\n");
|
||||
|
||||
PQclear(result);
|
||||
}
|
||||
|
||||
|
||||
+65
-1
@@ -84,5 +84,69 @@ pqt_get_bytea(PGtypeArgs *args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pqt_put_bit(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;
|
||||
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);
|
||||
return total_bytes;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pqt_get_bit(PGtypeArgs *args)
|
||||
{
|
||||
DECLVALUE(args);
|
||||
DECLLENGTH(args);
|
||||
PGbit *bit = va_arg(args->ap, PGbit *);
|
||||
CHKGETVALS(args, bit);
|
||||
if (args->format == TEXTFMT)
|
||||
{
|
||||
unsigned char *cur_byte;
|
||||
char *cur_char;
|
||||
unsigned char mask_byte;
|
||||
uint32_t len_bits = (uint32_t)strlen(value);
|
||||
int len_bytes = (len_bits >> 3) + !!(len_bits & 07);
|
||||
char *data = (char *)PQresultAlloc(args->get.result, (size_t)len_bytes);
|
||||
if (!data)
|
||||
RERR_MEM(args);
|
||||
cur_byte = (unsigned char *)data;
|
||||
*cur_byte = 0;
|
||||
mask_byte = 0x80;
|
||||
for (cur_char = value; *cur_char; ++cur_char)
|
||||
{
|
||||
if (*cur_char == '1')
|
||||
*cur_byte |= mask_byte;
|
||||
else if (*cur_char != '0')
|
||||
{
|
||||
PQfreemem(data);
|
||||
RERR(args, "String to bit string conversion failed");
|
||||
}
|
||||
mask_byte >>= 1;
|
||||
if (mask_byte == 0)
|
||||
{
|
||||
++cur_byte;
|
||||
*cur_byte = 0;
|
||||
mask_byte = 0x80;
|
||||
}
|
||||
}
|
||||
bit->len_bytes = len_bytes;
|
||||
bit->len_bits = (int32_t)len_bits;
|
||||
bit->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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user