@@ -1249,77 +1249,49 @@ Datum
1249
1249
hstore_to_json_loose (PG_FUNCTION_ARGS )
1250
1250
{
1251
1251
HStore * in = PG_GETARG_HS (0 );
1252
- int buflen ,
1253
- i ;
1252
+ int i ;
1254
1253
int count = HS_COUNT (in );
1255
- char * out ,
1256
- * ptr ;
1257
1254
char * base = STRPTR (in );
1258
1255
HEntry * entries = ARRPTR (in );
1259
1256
bool is_number ;
1260
- StringInfo src ,
1257
+ StringInfoData tmp ,
1261
1258
dst ;
1262
1259
1263
1260
if (count == 0 )
1264
1261
PG_RETURN_TEXT_P (cstring_to_text_with_len ("{}" ,2 ));
1265
1262
1266
- buflen = 3 ;
1263
+ initStringInfo (& tmp );
1264
+ initStringInfo (& dst );
1267
1265
1268
- /*
1269
- * Formula adjusted slightly from the logic in hstore_out. We have to take
1270
- * account of out treatment of booleans to be a bit more pessimistic about
1271
- * the length of values.
1272
- */
1266
+ appendStringInfoChar (& dst ,'{' );
1273
1267
1274
1268
for (i = 0 ;i < count ;i ++ )
1275
1269
{
1276
- /* include "" and colon-space and comma-space */
1277
- buflen += 6 + 2 * HS_KEYLEN (entries ,i );
1278
- /* include "" only if nonnull */
1279
- buflen += 3 + (HS_VALISNULL (entries ,i )
1280
- ?1
1281
- :2 * HS_VALLEN (entries ,i ));
1282
- }
1283
-
1284
- out = ptr = palloc (buflen );
1285
-
1286
- src = makeStringInfo ();
1287
- dst = makeStringInfo ();
1288
-
1289
- * ptr ++ = '{' ;
1290
-
1291
- for (i = 0 ;i < count ;i ++ )
1292
- {
1293
- resetStringInfo (src );
1294
- resetStringInfo (dst );
1295
- appendBinaryStringInfo (src ,HS_KEY (entries ,base ,i ),HS_KEYLEN (entries ,i ));
1296
- escape_json (dst ,src -> data );
1297
- strncpy (ptr ,dst -> data ,dst -> len );
1298
- ptr += dst -> len ;
1299
- * ptr ++ = ':' ;
1300
- * ptr ++ = ' ' ;
1301
- resetStringInfo (dst );
1270
+ resetStringInfo (& tmp );
1271
+ appendBinaryStringInfo (& tmp ,HS_KEY (entries ,base ,i ),HS_KEYLEN (entries ,i ));
1272
+ escape_json (& dst ,tmp .data );
1273
+ appendStringInfoString (& dst ,": " );
1302
1274
if (HS_VALISNULL (entries ,i ))
1303
- appendStringInfoString (dst ,"null" );
1275
+ appendStringInfoString (& dst ,"null" );
1304
1276
/* guess that values of 't' or 'f' are booleans */
1305
1277
else if (HS_VALLEN (entries ,i )== 1 && * (HS_VAL (entries ,base ,i ))== 't' )
1306
- appendStringInfoString (dst ,"true" );
1278
+ appendStringInfoString (& dst ,"true" );
1307
1279
else if (HS_VALLEN (entries ,i )== 1 && * (HS_VAL (entries ,base ,i ))== 'f' )
1308
- appendStringInfoString (dst ,"false" );
1280
+ appendStringInfoString (& dst ,"false" );
1309
1281
else
1310
1282
{
1311
1283
is_number = false;
1312
- resetStringInfo (src );
1313
- appendBinaryStringInfo (src ,HS_VAL (entries ,base ,i ),HS_VALLEN (entries ,i ));
1284
+ resetStringInfo (& tmp );
1285
+ appendBinaryStringInfo (& tmp ,HS_VAL (entries ,base ,i ),HS_VALLEN (entries ,i ));
1314
1286
1315
1287
/*
1316
1288
* don't treat something with a leading zero followed by another
1317
1289
* digit as numeric - could be a zip code or similar
1318
1290
*/
1319
- if (src -> len > 0 &&
1320
- !(src -> data [0 ]== '0' &&
1321
- isdigit ((unsignedchar )src -> data [1 ]))&&
1322
- strspn (src -> data ,"+-0123456789Ee." )== src -> len )
1291
+ if (tmp . len > 0 &&
1292
+ !(tmp . data [0 ]== '0' &&
1293
+ isdigit ((unsignedchar )tmp . data [1 ]))&&
1294
+ strspn (tmp . data ,"+-0123456789Ee." )== tmp . len )
1323
1295
{
1324
1296
/*
1325
1297
* might be a number. See if we can input it as a numeric
@@ -1328,7 +1300,7 @@ hstore_to_json_loose(PG_FUNCTION_ARGS)
1328
1300
char * endptr = "junk" ;
1329
1301
long lval ;
1330
1302
1331
- lval = strtol (src -> data ,& endptr ,10 );
1303
+ lval = strtol (tmp . data ,& endptr ,10 );
1332
1304
(void )lval ;
1333
1305
if (* endptr == '\0' )
1334
1306
{
@@ -1343,30 +1315,24 @@ hstore_to_json_loose(PG_FUNCTION_ARGS)
1343
1315
/* not an int - try a double */
1344
1316
double dval ;
1345
1317
1346
- dval = strtod (src -> data ,& endptr );
1318
+ dval = strtod (tmp . data ,& endptr );
1347
1319
(void )dval ;
1348
1320
if (* endptr == '\0' )
1349
1321
is_number = true;
1350
1322
}
1351
1323
}
1352
1324
if (is_number )
1353
- appendBinaryStringInfo (dst ,src -> data ,src -> len );
1325
+ appendBinaryStringInfo (& dst ,tmp . data ,tmp . len );
1354
1326
else
1355
- escape_json (dst ,src -> data );
1327
+ escape_json (& dst ,tmp . data );
1356
1328
}
1357
- strncpy (ptr ,dst -> data ,dst -> len );
1358
- ptr += dst -> len ;
1359
1329
1360
1330
if (i + 1 != count )
1361
- {
1362
- * ptr ++ = ',' ;
1363
- * ptr ++ = ' ' ;
1364
- }
1331
+ appendStringInfoString (& dst ,", " );
1365
1332
}
1366
- * ptr ++ = '}' ;
1367
- * ptr = '\0' ;
1333
+ appendStringInfoChar (& dst ,'}' );
1368
1334
1369
- PG_RETURN_TEXT_P (cstring_to_text (out ));
1335
+ PG_RETURN_TEXT_P (cstring_to_text (dst . data ));
1370
1336
}
1371
1337
1372
1338
PG_FUNCTION_INFO_V1 (hstore_to_json );
@@ -1375,74 +1341,40 @@ Datum
1375
1341
hstore_to_json (PG_FUNCTION_ARGS )
1376
1342
{
1377
1343
HStore * in = PG_GETARG_HS (0 );
1378
- int buflen ,
1379
- i ;
1344
+ int i ;
1380
1345
int count = HS_COUNT (in );
1381
- char * out ,
1382
- * ptr ;
1383
1346
char * base = STRPTR (in );
1384
1347
HEntry * entries = ARRPTR (in );
1385
- StringInfo src ,
1348
+ StringInfoData tmp ,
1386
1349
dst ;
1387
1350
1388
1351
if (count == 0 )
1389
1352
PG_RETURN_TEXT_P (cstring_to_text_with_len ("{}" ,2 ));
1390
1353
1391
- buflen = 3 ;
1354
+ initStringInfo (& tmp );
1355
+ initStringInfo (& dst );
1392
1356
1393
- /*
1394
- * Formula adjusted slightly from the logic in hstore_out. We have to take
1395
- * account of out treatment of booleans to be a bit more pessimistic about
1396
- * the length of values.
1397
- */
1357
+ appendStringInfoChar (& dst ,'{' );
1398
1358
1399
1359
for (i = 0 ;i < count ;i ++ )
1400
1360
{
1401
- /* include "" and colon-space and comma-space */
1402
- buflen += 6 + 2 * HS_KEYLEN (entries ,i );
1403
- /* include "" only if nonnull */
1404
- buflen += 3 + (HS_VALISNULL (entries ,i )
1405
- ?1
1406
- :2 * HS_VALLEN (entries ,i ));
1407
- }
1408
-
1409
- out = ptr = palloc (buflen );
1410
-
1411
- src = makeStringInfo ();
1412
- dst = makeStringInfo ();
1413
-
1414
- * ptr ++ = '{' ;
1415
-
1416
- for (i = 0 ;i < count ;i ++ )
1417
- {
1418
- resetStringInfo (src );
1419
- resetStringInfo (dst );
1420
- appendBinaryStringInfo (src ,HS_KEY (entries ,base ,i ),HS_KEYLEN (entries ,i ));
1421
- escape_json (dst ,src -> data );
1422
- strncpy (ptr ,dst -> data ,dst -> len );
1423
- ptr += dst -> len ;
1424
- * ptr ++ = ':' ;
1425
- * ptr ++ = ' ' ;
1426
- resetStringInfo (dst );
1361
+ resetStringInfo (& tmp );
1362
+ appendBinaryStringInfo (& tmp ,HS_KEY (entries ,base ,i ),HS_KEYLEN (entries ,i ));
1363
+ escape_json (& dst ,tmp .data );
1364
+ appendStringInfoString (& dst ,": " );
1427
1365
if (HS_VALISNULL (entries ,i ))
1428
- appendStringInfoString (dst ,"null" );
1366
+ appendStringInfoString (& dst ,"null" );
1429
1367
else
1430
1368
{
1431
- resetStringInfo (src );
1432
- appendBinaryStringInfo (src ,HS_VAL (entries ,base ,i ),HS_VALLEN (entries ,i ));
1433
- escape_json (dst ,src -> data );
1369
+ resetStringInfo (& tmp );
1370
+ appendBinaryStringInfo (& tmp ,HS_VAL (entries ,base ,i ),HS_VALLEN (entries ,i ));
1371
+ escape_json (& dst ,tmp . data );
1434
1372
}
1435
- strncpy (ptr ,dst -> data ,dst -> len );
1436
- ptr += dst -> len ;
1437
1373
1438
1374
if (i + 1 != count )
1439
- {
1440
- * ptr ++ = ',' ;
1441
- * ptr ++ = ' ' ;
1442
- }
1375
+ appendStringInfoString (& dst ,", " );
1443
1376
}
1444
- * ptr ++ = '}' ;
1445
- * ptr = '\0' ;
1377
+ appendStringInfoChar (& dst ,'}' );
1446
1378
1447
- PG_RETURN_TEXT_P (cstring_to_text (out ));
1379
+ PG_RETURN_TEXT_P (cstring_to_text (dst . data ));
1448
1380
}