@ -1245,77 +1245,49 @@ Datum
hstore_to_json_loose ( PG_FUNCTION_ARGS )
hstore_to_json_loose ( PG_FUNCTION_ARGS )
{
{
HStore * in = PG_GETARG_HS ( 0 ) ;
HStore * in = PG_GETARG_HS ( 0 ) ;
int buflen ,
int i ;
i ;
int count = HS_COUNT ( in ) ;
int count = HS_COUNT ( in ) ;
char * out ,
* ptr ;
char * base = STRPTR ( in ) ;
char * base = STRPTR ( in ) ;
HEntry * entries = ARRPTR ( in ) ;
HEntry * entries = ARRPTR ( in ) ;
bool is_number ;
bool is_number ;
StringInfo src ,
StringInfoData tmp ,
dst ;
dst ;
if ( count = = 0 )
if ( count = = 0 )
PG_RETURN_TEXT_P ( cstring_to_text_with_len ( " {} " , 2 ) ) ;
PG_RETURN_TEXT_P ( cstring_to_text_with_len ( " {} " , 2 ) ) ;
buflen = 3 ;
initStringInfo ( & tmp ) ;
initStringInfo ( & dst ) ;
/*
appendStringInfoChar ( & dst , ' { ' ) ;
* Formula adjusted slightly from the logic in hstore_out . We have to take
* account of out treatment of booleans to be a bit more pessimistic about
* the length of values .
*/
for ( i = 0 ; i < count ; i + + )
for ( i = 0 ; i < count ; i + + )
{
{
/* include "" and colon-space and comma-space */
resetStringInfo ( & tmp ) ;
buflen + = 6 + 2 * HS_KEYLEN ( entries , i ) ;
appendBinaryStringInfo ( & tmp , HS_KEY ( entries , base , i ) , HS_KEYLEN ( entries , i ) ) ;
/* include "" only if nonnull */
escape_json ( & dst , tmp . data ) ;
buflen + = 3 + ( HS_VALISNULL ( entries , i )
appendStringInfoString ( & dst , " : " ) ;
? 1
: 2 * HS_VALLEN ( entries , i ) ) ;
}
out = ptr = palloc ( buflen ) ;
src = makeStringInfo ( ) ;
dst = makeStringInfo ( ) ;
* ptr + + = ' { ' ;
for ( i = 0 ; i < count ; i + + )
{
resetStringInfo ( src ) ;
resetStringInfo ( dst ) ;
appendBinaryStringInfo ( src , HS_KEY ( entries , base , i ) , HS_KEYLEN ( entries , i ) ) ;
escape_json ( dst , src - > data ) ;
strncpy ( ptr , dst - > data , dst - > len ) ;
ptr + = dst - > len ;
* ptr + + = ' : ' ;
* ptr + + = ' ' ;
resetStringInfo ( dst ) ;
if ( HS_VALISNULL ( entries , i ) )
if ( HS_VALISNULL ( entries , i ) )
appendStringInfoString ( dst , " null " ) ;
appendStringInfoString ( & dst , " null " ) ;
/* guess that values of 't' or 'f' are booleans */
/* guess that values of 't' or 'f' are booleans */
else if ( HS_VALLEN ( entries , i ) = = 1 & & * ( HS_VAL ( entries , base , i ) ) = = ' t ' )
else if ( HS_VALLEN ( entries , i ) = = 1 & & * ( HS_VAL ( entries , base , i ) ) = = ' t ' )
appendStringInfoString ( dst , " true " ) ;
appendStringInfoString ( & dst , " true " ) ;
else if ( HS_VALLEN ( entries , i ) = = 1 & & * ( HS_VAL ( entries , base , i ) ) = = ' f ' )
else if ( HS_VALLEN ( entries , i ) = = 1 & & * ( HS_VAL ( entries , base , i ) ) = = ' f ' )
appendStringInfoString ( dst , " false " ) ;
appendStringInfoString ( & dst , " false " ) ;
else
else
{
{
is_number = false ;
is_number = false ;
resetStringInfo ( src ) ;
resetStringInfo ( & tmp ) ;
appendBinaryStringInfo ( src , HS_VAL ( entries , base , i ) , HS_VALLEN ( entries , i ) ) ;
appendBinaryStringInfo ( & tmp , HS_VAL ( entries , base , i ) , HS_VALLEN ( entries , i ) ) ;
/*
/*
* don ' t treat something with a leading zero followed by another
* don ' t treat something with a leading zero followed by another
* digit as numeric - could be a zip code or similar
* digit as numeric - could be a zip code or similar
*/
*/
if ( src - > len > 0 & &
if ( tmp . len > 0 & &
! ( src - > data [ 0 ] = = ' 0 ' & &
! ( tmp . data [ 0 ] = = ' 0 ' & &
isdigit ( ( unsigned char ) src - > data [ 1 ] ) ) & &
isdigit ( ( unsigned char ) tmp . data [ 1 ] ) ) & &
strspn ( src - > data , " +-0123456789Ee. " ) = = src - > len )
strspn ( tmp . data , " +-0123456789Ee. " ) = = tmp . len )
{
{
/*
/*
* might be a number . See if we can input it as a numeric
* might be a number . See if we can input it as a numeric
@ -1324,7 +1296,7 @@ hstore_to_json_loose(PG_FUNCTION_ARGS)
char * endptr = " junk " ;
char * endptr = " junk " ;
long lval ;
long lval ;
lval = strtol ( src - > data , & endptr , 10 ) ;
lval = strtol ( tmp . data , & endptr , 10 ) ;
( void ) lval ;
( void ) lval ;
if ( * endptr = = ' \0 ' )
if ( * endptr = = ' \0 ' )
{
{
@ -1339,30 +1311,24 @@ hstore_to_json_loose(PG_FUNCTION_ARGS)
/* not an int - try a double */
/* not an int - try a double */
double dval ;
double dval ;
dval = strtod ( src - > data , & endptr ) ;
dval = strtod ( tmp . data , & endptr ) ;
( void ) dval ;
( void ) dval ;
if ( * endptr = = ' \0 ' )
if ( * endptr = = ' \0 ' )
is_number = true ;
is_number = true ;
}
}
}
}
if ( is_number )
if ( is_number )
appendBinaryStringInfo ( dst , src - > data , src - > len ) ;
appendBinaryStringInfo ( & dst , tmp . data , tmp . len ) ;
else
else
escape_json ( dst , src - > data ) ;
escape_json ( & dst , tmp . data ) ;
}
}
strncpy ( ptr , dst - > data , dst - > len ) ;
ptr + = dst - > len ;
if ( i + 1 ! = count )
if ( i + 1 ! = count )
{
appendStringInfoString ( & dst , " , " ) ;
* ptr + + = ' , ' ;
* ptr + + = ' ' ;
}
}
}
* ptr + + = ' } ' ;
appendStringInfoChar ( & dst , ' } ' ) ;
* ptr = ' \0 ' ;
PG_RETURN_TEXT_P ( cstring_to_text ( out ) ) ;
PG_RETURN_TEXT_P ( cstring_to_text ( dst . data ) ) ;
}
}
PG_FUNCTION_INFO_V1 ( hstore_to_json ) ;
PG_FUNCTION_INFO_V1 ( hstore_to_json ) ;
@ -1371,74 +1337,40 @@ Datum
hstore_to_json ( PG_FUNCTION_ARGS )
hstore_to_json ( PG_FUNCTION_ARGS )
{
{
HStore * in = PG_GETARG_HS ( 0 ) ;
HStore * in = PG_GETARG_HS ( 0 ) ;
int buflen ,
int i ;
i ;
int count = HS_COUNT ( in ) ;
int count = HS_COUNT ( in ) ;
char * out ,
* ptr ;
char * base = STRPTR ( in ) ;
char * base = STRPTR ( in ) ;
HEntry * entries = ARRPTR ( in ) ;
HEntry * entries = ARRPTR ( in ) ;
StringInfo src ,
StringInfoData tmp ,
dst ;
dst ;
if ( count = = 0 )
if ( count = = 0 )
PG_RETURN_TEXT_P ( cstring_to_text_with_len ( " {} " , 2 ) ) ;
PG_RETURN_TEXT_P ( cstring_to_text_with_len ( " {} " , 2 ) ) ;
buflen = 3 ;
initStringInfo ( & tmp ) ;
initStringInfo ( & dst ) ;
/*
appendStringInfoChar ( & dst , ' { ' ) ;
* Formula adjusted slightly from the logic in hstore_out . We have to take
* account of out treatment of booleans to be a bit more pessimistic about
* the length of values .
*/
for ( i = 0 ; i < count ; i + + )
for ( i = 0 ; i < count ; i + + )
{
{
/* include "" and colon-space and comma-space */
resetStringInfo ( & tmp ) ;
buflen + = 6 + 2 * HS_KEYLEN ( entries , i ) ;
appendBinaryStringInfo ( & tmp , HS_KEY ( entries , base , i ) , HS_KEYLEN ( entries , i ) ) ;
/* include "" only if nonnull */
escape_json ( & dst , tmp . data ) ;
buflen + = 3 + ( HS_VALISNULL ( entries , i )
appendStringInfoString ( & dst , " : " ) ;
? 1
: 2 * HS_VALLEN ( entries , i ) ) ;
}
out = ptr = palloc ( buflen ) ;
src = makeStringInfo ( ) ;
dst = makeStringInfo ( ) ;
* ptr + + = ' { ' ;
for ( i = 0 ; i < count ; i + + )
{
resetStringInfo ( src ) ;
resetStringInfo ( dst ) ;
appendBinaryStringInfo ( src , HS_KEY ( entries , base , i ) , HS_KEYLEN ( entries , i ) ) ;
escape_json ( dst , src - > data ) ;
strncpy ( ptr , dst - > data , dst - > len ) ;
ptr + = dst - > len ;
* ptr + + = ' : ' ;
* ptr + + = ' ' ;
resetStringInfo ( dst ) ;
if ( HS_VALISNULL ( entries , i ) )
if ( HS_VALISNULL ( entries , i ) )
appendStringInfoString ( dst , " null " ) ;
appendStringInfoString ( & dst , " null " ) ;
else
else
{
{
resetStringInfo ( src ) ;
resetStringInfo ( & tmp ) ;
appendBinaryStringInfo ( src , HS_VAL ( entries , base , i ) , HS_VALLEN ( entries , i ) ) ;
appendBinaryStringInfo ( & tmp , HS_VAL ( entries , base , i ) , HS_VALLEN ( entries , i ) ) ;
escape_json ( dst , src - > data ) ;
escape_json ( & dst , tmp . data ) ;
}
}
strncpy ( ptr , dst - > data , dst - > len ) ;
ptr + = dst - > len ;
if ( i + 1 ! = count )
if ( i + 1 ! = count )
{
appendStringInfoString ( & dst , " , " ) ;
* ptr + + = ' , ' ;
* ptr + + = ' ' ;
}
}
}
* ptr + + = ' } ' ;
appendStringInfoChar ( & dst , ' } ' ) ;
* ptr = ' \0 ' ;
PG_RETURN_TEXT_P ( cstring_to_text ( out ) ) ;
PG_RETURN_TEXT_P ( cstring_to_text ( dst . data ) ) ;
}
}