@@ -1245,77 +1245,49 @@ Datum
12451245hstore_to_json_loose (PG_FUNCTION_ARGS )
12461246{
12471247 HStore * in = PG_GETARG_HS (0 );
1248- int buflen ,
1249- i ;
1248+ int i ;
12501249 int count = HS_COUNT (in );
1251- char * out ,
1252- * ptr ;
12531250 char * base = STRPTR (in );
12541251 HEntry * entries = ARRPTR (in );
12551252 bool is_number ;
1256- StringInfo src ,
1253+ StringInfoData tmp ,
12571254 dst ;
12581255
12591256 if (count == 0 )
12601257 PG_RETURN_TEXT_P (cstring_to_text_with_len ("{}" ,2 ));
12611258
1262- buflen = 3 ;
1259+ initStringInfo (& tmp );
1260+ initStringInfo (& dst );
12631261
1264- /*
1265- * Formula adjusted slightly from the logic in hstore_out. We have to take
1266- * account of out treatment of booleans to be a bit more pessimistic about
1267- * the length of values.
1268- */
1262+ appendStringInfoChar (& dst , '{' );
12691263
12701264 for (i = 0 ; i < count ; i ++ )
12711265 {
1272- /* include "" and colon-space and comma-space */
1273- buflen += 6 + 2 * HS_KEYLEN (entries , i );
1274- /* include "" only if nonnull */
1275- buflen += 3 + (HS_VALISNULL (entries , i )
1276- ? 1
1277- : 2 * HS_VALLEN (entries , i ));
1278- }
1279-
1280- out = ptr = palloc (buflen );
1281-
1282- src = makeStringInfo ();
1283- dst = makeStringInfo ();
1284-
1285- * ptr ++ = '{' ;
1286-
1287- for (i = 0 ; i < count ; i ++ )
1288- {
1289- resetStringInfo (src );
1290- resetStringInfo (dst );
1291- appendBinaryStringInfo (src , HS_KEY (entries , base , i ), HS_KEYLEN (entries , i ));
1292- escape_json (dst , src -> data );
1293- strncpy (ptr , dst -> data , dst -> len );
1294- ptr += dst -> len ;
1295- * ptr ++ = ':' ;
1296- * ptr ++ = ' ' ;
1297- resetStringInfo (dst );
1266+ resetStringInfo (& tmp );
1267+ appendBinaryStringInfo (& tmp , HS_KEY (entries , base , i ), HS_KEYLEN (entries , i ));
1268+ escape_json (& dst , tmp .data );
1269+ appendStringInfoString (& dst , ": " );
12981270 if (HS_VALISNULL (entries , i ))
1299- appendStringInfoString (dst , "null" );
1271+ appendStringInfoString (& dst , "null" );
13001272 /* guess that values of 't' or 'f' are booleans */
13011273 else if (HS_VALLEN (entries , i ) == 1 && * (HS_VAL (entries , base , i )) == 't' )
1302- appendStringInfoString (dst , "true" );
1274+ appendStringInfoString (& dst , "true" );
13031275 else if (HS_VALLEN (entries , i ) == 1 && * (HS_VAL (entries , base , i )) == 'f' )
1304- appendStringInfoString (dst , "false" );
1276+ appendStringInfoString (& dst , "false" );
13051277 else
13061278 {
13071279 is_number = false;
1308- resetStringInfo (src );
1309- appendBinaryStringInfo (src , HS_VAL (entries , base , i ), HS_VALLEN (entries , i ));
1280+ resetStringInfo (& tmp );
1281+ appendBinaryStringInfo (& tmp , HS_VAL (entries , base , i ), HS_VALLEN (entries , i ));
13101282
13111283 /*
13121284 * don't treat something with a leading zero followed by another
13131285 * digit as numeric - could be a zip code or similar
13141286 */
1315- if (src -> len > 0 &&
1316- !(src -> data [0 ] == '0' &&
1317- isdigit ((unsigned char ) src -> data [1 ])) &&
1318- strspn (src -> data , "+-0123456789Ee." ) == src -> len )
1287+ if (tmp . len > 0 &&
1288+ !(tmp . data [0 ] == '0' &&
1289+ isdigit ((unsigned char ) tmp . data [1 ])) &&
1290+ strspn (tmp . data , "+-0123456789Ee." ) == tmp . len )
13191291 {
13201292 /*
13211293 * might be a number. See if we can input it as a numeric
@@ -1324,7 +1296,7 @@ hstore_to_json_loose(PG_FUNCTION_ARGS)
13241296 char * endptr = "junk" ;
13251297 long lval ;
13261298
1327- lval = strtol (src -> data , & endptr , 10 );
1299+ lval = strtol (tmp . data , & endptr , 10 );
13281300 (void ) lval ;
13291301 if (* endptr == '\0' )
13301302 {
@@ -1339,30 +1311,24 @@ hstore_to_json_loose(PG_FUNCTION_ARGS)
13391311 /* not an int - try a double */
13401312 double dval ;
13411313
1342- dval = strtod (src -> data , & endptr );
1314+ dval = strtod (tmp . data , & endptr );
13431315 (void ) dval ;
13441316 if (* endptr == '\0' )
13451317 is_number = true;
13461318 }
13471319 }
13481320 if (is_number )
1349- appendBinaryStringInfo (dst , src -> data , src -> len );
1321+ appendBinaryStringInfo (& dst , tmp . data , tmp . len );
13501322 else
1351- escape_json (dst , src -> data );
1323+ escape_json (& dst , tmp . data );
13521324 }
1353- strncpy (ptr , dst -> data , dst -> len );
1354- ptr += dst -> len ;
13551325
13561326 if (i + 1 != count )
1357- {
1358- * ptr ++ = ',' ;
1359- * ptr ++ = ' ' ;
1360- }
1327+ appendStringInfoString (& dst , ", " );
13611328 }
1362- * ptr ++ = '}' ;
1363- * ptr = '\0' ;
1329+ appendStringInfoChar (& dst , '}' );
13641330
1365- PG_RETURN_TEXT_P (cstring_to_text (out ));
1331+ PG_RETURN_TEXT_P (cstring_to_text (dst . data ));
13661332}
13671333
13681334PG_FUNCTION_INFO_V1 (hstore_to_json );
@@ -1371,74 +1337,40 @@ Datum
13711337hstore_to_json (PG_FUNCTION_ARGS )
13721338{
13731339 HStore * in = PG_GETARG_HS (0 );
1374- int buflen ,
1375- i ;
1340+ int i ;
13761341 int count = HS_COUNT (in );
1377- char * out ,
1378- * ptr ;
13791342 char * base = STRPTR (in );
13801343 HEntry * entries = ARRPTR (in );
1381- StringInfo src ,
1344+ StringInfoData tmp ,
13821345 dst ;
13831346
13841347 if (count == 0 )
13851348 PG_RETURN_TEXT_P (cstring_to_text_with_len ("{}" ,2 ));
13861349
1387- buflen = 3 ;
1350+ initStringInfo (& tmp );
1351+ initStringInfo (& dst );
13881352
1389- /*
1390- * Formula adjusted slightly from the logic in hstore_out. We have to take
1391- * account of out treatment of booleans to be a bit more pessimistic about
1392- * the length of values.
1393- */
1353+ appendStringInfoChar (& dst , '{' );
13941354
13951355 for (i = 0 ; i < count ; i ++ )
13961356 {
1397- /* include "" and colon-space and comma-space */
1398- buflen += 6 + 2 * HS_KEYLEN (entries , i );
1399- /* include "" only if nonnull */
1400- buflen += 3 + (HS_VALISNULL (entries , i )
1401- ? 1
1402- : 2 * HS_VALLEN (entries , i ));
1403- }
1404-
1405- out = ptr = palloc (buflen );
1406-
1407- src = makeStringInfo ();
1408- dst = makeStringInfo ();
1409-
1410- * ptr ++ = '{' ;
1411-
1412- for (i = 0 ; i < count ; i ++ )
1413- {
1414- resetStringInfo (src );
1415- resetStringInfo (dst );
1416- appendBinaryStringInfo (src , HS_KEY (entries , base , i ), HS_KEYLEN (entries , i ));
1417- escape_json (dst , src -> data );
1418- strncpy (ptr , dst -> data , dst -> len );
1419- ptr += dst -> len ;
1420- * ptr ++ = ':' ;
1421- * ptr ++ = ' ' ;
1422- resetStringInfo (dst );
1357+ resetStringInfo (& tmp );
1358+ appendBinaryStringInfo (& tmp , HS_KEY (entries , base , i ), HS_KEYLEN (entries , i ));
1359+ escape_json (& dst , tmp .data );
1360+ appendStringInfoString (& dst , ": " );
14231361 if (HS_VALISNULL (entries , i ))
1424- appendStringInfoString (dst , "null" );
1362+ appendStringInfoString (& dst , "null" );
14251363 else
14261364 {
1427- resetStringInfo (src );
1428- appendBinaryStringInfo (src , HS_VAL (entries , base , i ), HS_VALLEN (entries , i ));
1429- escape_json (dst , src -> data );
1365+ resetStringInfo (& tmp );
1366+ appendBinaryStringInfo (& tmp , HS_VAL (entries , base , i ), HS_VALLEN (entries , i ));
1367+ escape_json (& dst , tmp . data );
14301368 }
1431- strncpy (ptr , dst -> data , dst -> len );
1432- ptr += dst -> len ;
14331369
14341370 if (i + 1 != count )
1435- {
1436- * ptr ++ = ',' ;
1437- * ptr ++ = ' ' ;
1438- }
1371+ appendStringInfoString (& dst , ", " );
14391372 }
1440- * ptr ++ = '}' ;
1441- * ptr = '\0' ;
1373+ appendStringInfoChar (& dst , '}' );
14421374
1443- PG_RETURN_TEXT_P (cstring_to_text (out ));
1375+ PG_RETURN_TEXT_P (cstring_to_text (dst . data ));
14441376}
0 commit comments