@@ -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