Skip to content

Commit 9163b39

Browse files
committed
Add bytea IO functions
1 parent f80a845 commit 9163b39

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

sql/pgmp.pysql

+3-1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ castfrom('int8', implicit='I')
118118
castfrom('float4', implicit='A')
119119
castfrom('float8', implicit='A')
120120
castfrom('numeric', implicit='A')
121+
castfrom('bytea', implicit='A')
121122

122123
def castto(typname, implicit=False):
123124
"""Create a cast from `base_type` to a different type"""
@@ -134,6 +135,7 @@ castto('int4', implicit='A')
134135
castto('int2', implicit='A')
135136
castto('float4', implicit='A')
136137
castto('float8', implicit='A')
138+
castto('bytea', implicit='A')
137139

138140
!! PYOFF
139141

@@ -288,7 +290,7 @@ CREATE OPERATOR <> (
288290

289291
def bop(sym, fname, comm, neg):
290292
"""Create an operator on `base_type` returning a bool"""
291-
func('%s_%s' % (base_type, fname),
293+
func('%s_%s' % (base_type, fname),
292294
base_type + " " + base_type, argout='boolean')
293295
fname1 = fname[0] + 't'
294296

src/pmpz_io.c

+54
Original file line numberDiff line numberDiff line change
@@ -390,3 +390,57 @@ PGMP_PG_FUNCTION(pmpz_to_float8)
390390
PG_RETURN_FLOAT8((float8)out);
391391
}
392392

393+
PGMP_PG_FUNCTION(pmpz_from_bytea)
394+
{
395+
bytea *data = PG_GETARG_BYTEA_PP(0);
396+
int data_len = VARSIZE_ANY_EXHDR(data);
397+
char *data_body = VARDATA_ANY(data);
398+
mpz_t result_z;
399+
400+
mpz_init(result_z);
401+
402+
if(data_len == 0) {
403+
PGMP_RETURN_MPZ(result_z);
404+
}
405+
406+
if(!(data_len & 7)) {
407+
mpz_import(result_z, data_len / 8, 1, 8, 1, 0, (uint64_t *)data_body);
408+
} else if(!(data_len & 3)) {
409+
mpz_import(result_z, data_len / 4, 1, 4, 1, 0, (uint32_t *)data_body);
410+
} else if(!(data_len & 1)) {
411+
mpz_import(result_z, data_len / 2, 1, 2, 1, 0, (uint16_t *)data_body);
412+
} else {
413+
mpz_import(result_z, data_len, 1, 1, 1, 0, data_body);
414+
}
415+
416+
PGMP_RETURN_MPZ(result_z);
417+
}
418+
419+
PGMP_PG_FUNCTION(pmpz_to_bytea)
420+
{
421+
const mpz_t z;
422+
bytea *result;
423+
char *result_body_u8;
424+
int body_len;
425+
426+
PGMP_GETARG_MPZ(z, 0);
427+
428+
body_len = (mpz_sizeinbase(z, 16) + 1) / 2;
429+
430+
result = malloc(VARHDRSZ + body_len);
431+
result_body_u8 = VARDATA(result);
432+
433+
if(!(body_len & 7)) {
434+
mpz_export((uint64_t *)result_body_u8, NULL, 1, 8, 1, 0, z);
435+
} else if(!(body_len & 3)) {
436+
mpz_export((uint32_t *)result_body_u8, NULL, 1, 4, 1, 0, z);
437+
} else if(!(body_len & 1)) {
438+
mpz_export((uint16_t *)result_body_u8, NULL, 1, 2, 1, 0, z);
439+
} else {
440+
mpz_export(result_body_u8, NULL, 1, 1, 1, 0, z);
441+
}
442+
443+
SET_VARSIZE(result, VARHDRSZ + body_len);
444+
445+
PG_RETURN_BYTEA_P(result);
446+
}

0 commit comments

Comments
 (0)