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:
vmgolovin
2020-02-03 18:22:50 +04:00
parent d096a85c32
commit 1047d59c49
5 changed files with 106 additions and 12 deletions
+5 -1
View File
@@ -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
+3 -1
View File
@@ -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
}
+8
View File
@@ -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
* ----------------
+25 -9
View File
@@ -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
View File
@@ -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;
}