Jsonb should always display leading zero
This commit is contained in:
@ -19,6 +19,7 @@
|
||||
#include "utils/jsonapi.h"
|
||||
#include "utils/jsonb.h"
|
||||
#include "knl/knl_thread.h"
|
||||
#include "miscadmin.h"
|
||||
|
||||
typedef struct JsonbInState {
|
||||
JsonbParseState *parseState;
|
||||
@ -374,78 +375,97 @@ char *JsonbToCString(StringInfo out, JsonbSuperHeader in, int estimated_len)
|
||||
JsonbValue v;
|
||||
int level = 0;
|
||||
bool redo_switch = false;
|
||||
|
||||
/*
|
||||
* Number in jsonb is stored by numeric, we should set display_leading_zero to on,
|
||||
* otherwise, "0.1" will be displayed as ".1", it is not supposed for a JSON data.
|
||||
*/
|
||||
unsigned int original_behavior = u_sess->utils_cxt.behavior_compat_flags;
|
||||
u_sess->utils_cxt.behavior_compat_flags = original_behavior | OPT_DISPLAY_LEADING_ZERO;
|
||||
|
||||
if (out == NULL)
|
||||
out = makeStringInfo();
|
||||
PG_TRY();
|
||||
{
|
||||
if (out == NULL)
|
||||
out = makeStringInfo();
|
||||
|
||||
enlargeStringInfo(out, (estimated_len >= 0) ? estimated_len : 64);
|
||||
it = JsonbIteratorInit(in);
|
||||
enlargeStringInfo(out, (estimated_len >= 0) ? estimated_len : 64);
|
||||
it = JsonbIteratorInit(in);
|
||||
|
||||
while (redo_switch || ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)) {
|
||||
redo_switch = false;
|
||||
switch (type) {
|
||||
case WJB_BEGIN_ARRAY:
|
||||
if (!first)
|
||||
appendBinaryStringInfo(out, ", ", 2);
|
||||
first = true;
|
||||
while (redo_switch || ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)) {
|
||||
redo_switch = false;
|
||||
switch (type) {
|
||||
case WJB_BEGIN_ARRAY:
|
||||
if (!first)
|
||||
appendBinaryStringInfo(out, ", ", 2);
|
||||
first = true;
|
||||
|
||||
if (!v.array.rawScalar)
|
||||
appendStringInfoChar(out, '[');
|
||||
level++;
|
||||
break;
|
||||
case WJB_BEGIN_OBJECT:
|
||||
if (!first)
|
||||
appendBinaryStringInfo(out, ", ", 2);
|
||||
first = true;
|
||||
appendStringInfoCharMacro(out, '{');
|
||||
if (!v.array.rawScalar)
|
||||
appendStringInfoChar(out, '[');
|
||||
level++;
|
||||
break;
|
||||
case WJB_BEGIN_OBJECT:
|
||||
if (!first)
|
||||
appendBinaryStringInfo(out, ", ", 2);
|
||||
first = true;
|
||||
appendStringInfoCharMacro(out, '{');
|
||||
|
||||
level++;
|
||||
break;
|
||||
case WJB_KEY:
|
||||
if (!first)
|
||||
appendBinaryStringInfo(out, ", ", 2);
|
||||
first = true;
|
||||
level++;
|
||||
break;
|
||||
case WJB_KEY:
|
||||
if (!first)
|
||||
appendBinaryStringInfo(out, ", ", 2);
|
||||
first = true;
|
||||
|
||||
/* json rules guarantee this is a string */
|
||||
jsonb_put_escaped_value(out, &v);
|
||||
appendBinaryStringInfo(out, ": ", 2);
|
||||
|
||||
type = JsonbIteratorNext(&it, &v, false);
|
||||
if (type == WJB_VALUE) {
|
||||
first = false;
|
||||
/* json rules guarantee this is a string */
|
||||
jsonb_put_escaped_value(out, &v);
|
||||
} else {
|
||||
Assert(type == WJB_BEGIN_OBJECT || type == WJB_BEGIN_ARRAY);
|
||||
/*
|
||||
* We need to rerun the current switch() since we need to
|
||||
* output the object which we just got from the iterator
|
||||
* before calling the iterator again.
|
||||
*/
|
||||
redo_switch = true;
|
||||
}
|
||||
break;
|
||||
case WJB_ELEM:
|
||||
if (!first)
|
||||
appendBinaryStringInfo(out, ", ", 2);
|
||||
else
|
||||
appendBinaryStringInfo(out, ": ", 2);
|
||||
|
||||
type = JsonbIteratorNext(&it, &v, false);
|
||||
if (type == WJB_VALUE) {
|
||||
first = false;
|
||||
jsonb_put_escaped_value(out, &v);
|
||||
} else {
|
||||
Assert(type == WJB_BEGIN_OBJECT || type == WJB_BEGIN_ARRAY);
|
||||
/*
|
||||
* We need to rerun the current switch() since we need to
|
||||
* output the object which we just got from the iterator
|
||||
* before calling the iterator again.
|
||||
*/
|
||||
redo_switch = true;
|
||||
}
|
||||
break;
|
||||
case WJB_ELEM:
|
||||
if (!first)
|
||||
appendBinaryStringInfo(out, ", ", 2);
|
||||
else
|
||||
first = false;
|
||||
jsonb_put_escaped_value(out, &v);
|
||||
break;
|
||||
case WJB_END_ARRAY:
|
||||
level--;
|
||||
if (!v.array.rawScalar)
|
||||
appendStringInfoChar(out, ']');
|
||||
first = false;
|
||||
jsonb_put_escaped_value(out, &v);
|
||||
break;
|
||||
case WJB_END_ARRAY:
|
||||
level--;
|
||||
if (!v.array.rawScalar)
|
||||
appendStringInfoChar(out, ']');
|
||||
first = false;
|
||||
break;
|
||||
case WJB_END_OBJECT:
|
||||
level--;
|
||||
appendStringInfoCharMacro(out, '}');
|
||||
first = false;
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unknown flag of jsonb iterator");
|
||||
break;
|
||||
case WJB_END_OBJECT:
|
||||
level--;
|
||||
appendStringInfoCharMacro(out, '}');
|
||||
first = false;
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unknown flag of jsonb iterator");
|
||||
}
|
||||
}
|
||||
|
||||
u_sess->utils_cxt.behavior_compat_flags = original_behavior;
|
||||
Assert(level == 0);
|
||||
}
|
||||
Assert(level == 0);
|
||||
PG_CATCH();
|
||||
{
|
||||
u_sess->utils_cxt.behavior_compat_flags = original_behavior;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
return out->data;
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ referenced column: jsonb
|
||||
SELECT '0.1'::jsonb; -- OK
|
||||
jsonb
|
||||
-------
|
||||
.1
|
||||
0.1
|
||||
(1 row)
|
||||
|
||||
SELECT '9223372036854775808'::jsonb; -- OK, even though it's too large for int8
|
||||
|
||||
@ -54,9 +54,9 @@ DETAIL: Token "." is invalid.
|
||||
CONTEXT: JSON data, line 1: -1.5e5....
|
||||
referenced column: jsonb
|
||||
select '-1.5e-5'::jsonb;
|
||||
jsonb
|
||||
----------
|
||||
-.000015
|
||||
jsonb
|
||||
-----------
|
||||
-0.000015
|
||||
(1 row)
|
||||
|
||||
select '-1.5e+5'::jsonb;
|
||||
@ -229,7 +229,7 @@ from cmpjsonb order by 1,2,3,4,5,6,7,8,9;
|
||||
"" | [] | -1 | f | t | t | t | f | f
|
||||
"a" | "b" | -1 | f | t | t | t | f | f
|
||||
"a" | "cc" | -1 | f | t | t | t | f | f
|
||||
"a" | -.586 | -1 | f | t | t | t | f | f
|
||||
"a" | -0.586 | -1 | f | t | t | t | f | f
|
||||
"aa" | "aa" | 0 | t | f | f | t | f | t
|
||||
"s" | ["s"] | -1 | f | t | t | t | f | f
|
||||
"true" | true | -1 | f | t | t | t | f | f
|
||||
@ -291,7 +291,7 @@ from cmpjsonb order by 1,2,3,4,5,6,7,8;
|
||||
"" | [] | f | t | t | t | f | f
|
||||
"a" | "b" | f | t | t | t | f | f
|
||||
"a" | "cc" | f | t | t | t | f | f
|
||||
"a" | -.586 | f | t | t | t | f | f
|
||||
"a" | -0.586 | f | t | t | t | f | f
|
||||
"aa" | "aa" | t | f | f | t | f | t
|
||||
"s" | ["s"] | f | t | t | t | f | f
|
||||
"true" | true | f | t | t | t | f | f
|
||||
|
||||
Reference in New Issue
Block a user