@ -8,18 +8,14 @@
# include <ctype.h>
# include "crc32.h"
# include "libpq/pqformat.h"
# include "ltree.h"
# include "utils/memutils.h"
PG_FUNCTION_INFO_V1 ( ltree_in ) ;
PG_FUNCTION_INFO_V1 ( ltree_out ) ;
PG_FUNCTION_INFO_V1 ( lquery_in ) ;
PG_FUNCTION_INFO_V1 ( lquery_out ) ;
typedef struct
{
char * start ;
const char * start ;
int len ; /* length in bytes */
int flag ;
int wlen ; /* length in characters */
@ -28,11 +24,14 @@ typedef struct
# define LTPRS_WAITNAME 0
# define LTPRS_WAITDELIM 1
Datum
ltree_in ( PG_FUNCTION_ARGS )
/*
* expects a null terminated string
* returns an ltree
*/
static ltree *
parse_ltree ( const char * buf )
{
char * buf = ( char * ) PG_GETARG_POINTER ( 0 ) ;
char * ptr ;
const char * ptr ;
nodeitem * list ,
* lptr ;
int num = 0 ,
@ -141,15 +140,18 @@ ltree_in(PG_FUNCTION_ARGS)
}
pfree ( list ) ;
PG_RETURN_POINTER ( result ) ;
return result ;
# undef UNCHAR
}
Datum
ltree_out ( PG_FUNCTION_ARGS )
/*
* expects an ltree
* returns a null terminated string
*/
static char *
deparse_ltree ( const ltree * in )
{
ltree * in = PG_GETARG_LTREE_P ( 0 ) ;
char * buf ,
* ptr ;
int i ;
@ -170,11 +172,84 @@ ltree_out(PG_FUNCTION_ARGS)
}
* ptr = ' \0 ' ;
PG_FREE_IF_COPY ( in , 0 ) ;
return buf ;
}
/*
* Basic ltree I / O functions
*/
PG_FUNCTION_INFO_V1 ( ltree_in ) ;
Datum
ltree_in ( PG_FUNCTION_ARGS )
{
char * buf = ( char * ) PG_GETARG_POINTER ( 0 ) ;
PG_RETURN_POINTER ( parse_ltree ( buf ) ) ;
}
PG_FUNCTION_INFO_V1 ( ltree_out ) ;
Datum
ltree_out ( PG_FUNCTION_ARGS )
{
ltree * in = PG_GETARG_LTREE_P ( 0 ) ;
PG_RETURN_POINTER ( deparse_ltree ( in ) ) ;
}
/*
* ltree type send function
*
* The type is sent as text in binary mode , so this is almost the same
* as the output function , but it ' s prefixed with a version number so we
* can change the binary format sent in future if necessary . For now ,
* only version 1 is supported .
*/
PG_FUNCTION_INFO_V1 ( ltree_send ) ;
Datum
ltree_send ( PG_FUNCTION_ARGS )
{
ltree * in = PG_GETARG_LTREE_P ( 0 ) ;
StringInfoData buf ;
int version = 1 ;
char * res = deparse_ltree ( in ) ;
pq_begintypsend ( & buf ) ;
pq_sendint8 ( & buf , version ) ;
pq_sendtext ( & buf , res , strlen ( res ) ) ;
pfree ( res ) ;
PG_RETURN_BYTEA_P ( pq_endtypsend ( & buf ) ) ;
}
/*
* ltree type recv function
*
* The type is sent as text in binary mode , so this is almost the same
* as the input function , but it ' s prefixed with a version number so we
* can change the binary format sent in future if necessary . For now ,
* only version 1 is supported .
*/
PG_FUNCTION_INFO_V1 ( ltree_recv ) ;
Datum
ltree_recv ( PG_FUNCTION_ARGS )
{
StringInfo buf = ( StringInfo ) PG_GETARG_POINTER ( 0 ) ;
int version = pq_getmsgint ( buf , 1 ) ;
char * str ;
int nbytes ;
ltree * res ;
PG_RETURN_POINTER ( buf ) ;
if ( version ! = 1 )
elog ( ERROR , " unsupported ltree version number %d " , version ) ;
str = pq_getmsgtext ( buf , buf - > len - buf - > cursor , & nbytes ) ;
res = parse_ltree ( str ) ;
pfree ( str ) ;
PG_RETURN_POINTER ( res ) ;
}
# define LQPRS_WAITLEVEL 0
# define LQPRS_WAITDELIM 1
# define LQPRS_WAITOPEN 2
@ -190,11 +265,14 @@ ltree_out(PG_FUNCTION_ARGS)
# define ITEMSIZE MAXALIGN(LQL_HDRSIZE+sizeof(nodeitem*))
# define NEXTLEV(x) ( (lquery_level*)( ((char*)(x)) + ITEMSIZE) )
Datum
lquery_in ( PG_FUNCTION_ARGS )
/*
* expects a null terminated string
* returns an lquery
*/
static lquery *
parse_lquery ( const char * buf )
{
char * buf = ( char * ) PG_GETARG_POINTER ( 0 ) ;
char * ptr ;
const char * ptr ;
int num = 0 ,
totallen = 0 ,
numOR = 0 ;
@ -563,15 +641,18 @@ lquery_in(PG_FUNCTION_ARGS)
}
pfree ( tmpql ) ;
PG_RETURN_POINTER ( result ) ;
return result ;
# undef UNCHAR
}
Datum
lquery_out ( PG_FUNCTION_ARGS )
/*
* expects an lquery
* returns a null terminated string
*/
static char *
deparse_lquery ( const lquery * in )
{
lquery * in = PG_GETARG_LQUERY_P ( 0 ) ;
char * buf ,
* ptr ;
int i ,
@ -679,7 +760,79 @@ lquery_out(PG_FUNCTION_ARGS)
}
* ptr = ' \0 ' ;
PG_FREE_IF_COPY ( in , 0 ) ;
return buf ;
}
/*
* Basic lquery I / O functions
*/
PG_FUNCTION_INFO_V1 ( lquery_in ) ;
Datum
lquery_in ( PG_FUNCTION_ARGS )
{
char * buf = ( char * ) PG_GETARG_POINTER ( 0 ) ;
PG_RETURN_POINTER ( parse_lquery ( buf ) ) ;
}
PG_FUNCTION_INFO_V1 ( lquery_out ) ;
Datum
lquery_out ( PG_FUNCTION_ARGS )
{
lquery * in = PG_GETARG_LQUERY_P ( 0 ) ;
PG_RETURN_POINTER ( deparse_lquery ( in ) ) ;
}
/*
* lquery type send function
*
* The type is sent as text in binary mode , so this is almost the same
* as the output function , but it ' s prefixed with a version number so we
* can change the binary format sent in future if necessary . For now ,
* only version 1 is supported .
*/
PG_FUNCTION_INFO_V1 ( lquery_send ) ;
Datum
lquery_send ( PG_FUNCTION_ARGS )
{
lquery * in = PG_GETARG_LQUERY_P ( 0 ) ;
StringInfoData buf ;
int version = 1 ;
char * res = deparse_lquery ( in ) ;
pq_begintypsend ( & buf ) ;
pq_sendint8 ( & buf , version ) ;
pq_sendtext ( & buf , res , strlen ( res ) ) ;
pfree ( res ) ;
PG_RETURN_BYTEA_P ( pq_endtypsend ( & buf ) ) ;
}
/*
* lquery type recv function
*
* The type is sent as text in binary mode , so this is almost the same
* as the input function , but it ' s prefixed with a version number so we
* can change the binary format sent in future if necessary . For now ,
* only version 1 is supported .
*/
PG_FUNCTION_INFO_V1 ( lquery_recv ) ;
Datum
lquery_recv ( PG_FUNCTION_ARGS )
{
StringInfo buf = ( StringInfo ) PG_GETARG_POINTER ( 0 ) ;
int version = pq_getmsgint ( buf , 1 ) ;
char * str ;
int nbytes ;
lquery * res ;
if ( version ! = 1 )
elog ( ERROR , " unsupported lquery version number %d " , version ) ;
str = pq_getmsgtext ( buf , buf - > len - buf - > cursor , & nbytes ) ;
res = parse_lquery ( str ) ;
pfree ( str ) ;
PG_RETURN_POINTER ( buf ) ;
PG_RETURN_POINTER ( res ) ;
}