@@ -1245,77 +1245,49 @@ Datum
1245
1245
hstore_to_json_loose (PG_FUNCTION_ARGS )
1246
1246
{
1247
1247
HStore * in = PG_GETARG_HS (0 );
1248
- int buflen ,
1249
- i ;
1248
+ int i ;
1250
1249
int count = HS_COUNT (in );
1251
- char * out ,
1252
- * ptr ;
1253
1250
char * base = STRPTR (in );
1254
1251
HEntry * entries = ARRPTR (in );
1255
1252
bool is_number ;
1256
- StringInfo src ,
1253
+ StringInfoData tmp ,
1257
1254
dst ;
1258
1255
1259
1256
if (count == 0 )
1260
1257
PG_RETURN_TEXT_P (cstring_to_text_with_len ("{}" ,2 ));
1261
1258
1262
- buflen = 3 ;
1259
+ initStringInfo (& tmp );
1260
+ initStringInfo (& dst );
1263
1261
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 , '{' );
1269
1263
1270
1264
for (i = 0 ; i < count ; i ++ )
1271
1265
{
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 , ": " );
1298
1270
if (HS_VALISNULL (entries , i ))
1299
- appendStringInfoString (dst , "null" );
1271
+ appendStringInfoString (& dst , "null" );
1300
1272
/* guess that values of 't' or 'f' are booleans */
1301
1273
else if (HS_VALLEN (entries , i ) == 1 && * (HS_VAL (entries , base , i )) == 't' )
1302
- appendStringInfoString (dst , "true" );
1274
+ appendStringInfoString (& dst , "true" );
1303
1275
else if (HS_VALLEN (entries , i ) == 1 && * (HS_VAL (entries , base , i )) == 'f' )
1304
- appendStringInfoString (dst , "false" );
1276
+ appendStringInfoString (& dst , "false" );
1305
1277
else
1306
1278
{
1307
1279
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 ));
1310
1282
1311
1283
/*
1312
1284
* don't treat something with a leading zero followed by another
1313
1285
* digit as numeric - could be a zip code or similar
1314
1286
*/
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 )
1319
1291
{
1320
1292
/*
1321
1293
* might be a number. See if we can input it as a numeric
@@ -1324,7 +1296,7 @@ hstore_to_json_loose(PG_FUNCTION_ARGS)
1324
1296
char * endptr = "junk" ;
1325
1297
long lval ;
1326
1298
1327
- lval = strtol (src -> data , & endptr , 10 );
1299
+ lval = strtol (tmp . data , & endptr , 10 );
1328
1300
(void ) lval ;
1329
1301
if (* endptr == '\0' )
1330
1302
{
@@ -1339,30 +1311,24 @@ hstore_to_json_loose(PG_FUNCTION_ARGS)
1339
1311
/* not an int - try a double */
1340
1312
double dval ;
1341
1313
1342
- dval = strtod (src -> data , & endptr );
1314
+ dval = strtod (tmp . data , & endptr );
1343
1315
(void ) dval ;
1344
1316
if (* endptr == '\0' )
1345
1317
is_number = true;
1346
1318
}
1347
1319
}
1348
1320
if (is_number )
1349
- appendBinaryStringInfo (dst , src -> data , src -> len );
1321
+ appendBinaryStringInfo (& dst , tmp . data , tmp . len );
1350
1322
else
1351
- escape_json (dst , src -> data );
1323
+ escape_json (& dst , tmp . data );
1352
1324
}
1353
- strncpy (ptr , dst -> data , dst -> len );
1354
- ptr += dst -> len ;
1355
1325
1356
1326
if (i + 1 != count )
1357
- {
1358
- * ptr ++ = ',' ;
1359
- * ptr ++ = ' ' ;
1360
- }
1327
+ appendStringInfoString (& dst , ", " );
1361
1328
}
1362
- * ptr ++ = '}' ;
1363
- * ptr = '\0' ;
1329
+ appendStringInfoChar (& dst , '}' );
1364
1330
1365
- PG_RETURN_TEXT_P (cstring_to_text (out ));
1331
+ PG_RETURN_TEXT_P (cstring_to_text (dst . data ));
1366
1332
}
1367
1333
1368
1334
PG_FUNCTION_INFO_V1 (hstore_to_json );
@@ -1371,74 +1337,40 @@ Datum
1371
1337
hstore_to_json (PG_FUNCTION_ARGS )
1372
1338
{
1373
1339
HStore * in = PG_GETARG_HS (0 );
1374
- int buflen ,
1375
- i ;
1340
+ int i ;
1376
1341
int count = HS_COUNT (in );
1377
- char * out ,
1378
- * ptr ;
1379
1342
char * base = STRPTR (in );
1380
1343
HEntry * entries = ARRPTR (in );
1381
- StringInfo src ,
1344
+ StringInfoData tmp ,
1382
1345
dst ;
1383
1346
1384
1347
if (count == 0 )
1385
1348
PG_RETURN_TEXT_P (cstring_to_text_with_len ("{}" ,2 ));
1386
1349
1387
- buflen = 3 ;
1350
+ initStringInfo (& tmp );
1351
+ initStringInfo (& dst );
1388
1352
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 , '{' );
1394
1354
1395
1355
for (i = 0 ; i < count ; i ++ )
1396
1356
{
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 , ": " );
1423
1361
if (HS_VALISNULL (entries , i ))
1424
- appendStringInfoString (dst , "null" );
1362
+ appendStringInfoString (& dst , "null" );
1425
1363
else
1426
1364
{
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 );
1430
1368
}
1431
- strncpy (ptr , dst -> data , dst -> len );
1432
- ptr += dst -> len ;
1433
1369
1434
1370
if (i + 1 != count )
1435
- {
1436
- * ptr ++ = ',' ;
1437
- * ptr ++ = ' ' ;
1438
- }
1371
+ appendStringInfoString (& dst , ", " );
1439
1372
}
1440
- * ptr ++ = '}' ;
1441
- * ptr = '\0' ;
1373
+ appendStringInfoChar (& dst , '}' );
1442
1374
1443
- PG_RETURN_TEXT_P (cstring_to_text (out ));
1375
+ PG_RETURN_TEXT_P (cstring_to_text (dst . data ));
1444
1376
}
0 commit comments