eulerto / wal2json

JSON output plugin for changeset extraction
BSD 3-Clause "New" or "Revised" License
1.33k stars 161 forks source link

Numeric/Decimals should be strings? #41

Closed rcoup closed 7 years ago

rcoup commented 7 years ago

NUMERICOID is encoded as a number in the JSON output, but decimals/numeric values are typically encoded as strings to preserve the precision and lengths without floating point abiguity. Gut feel is wal2json should do the same thing.

Thoughts?

eulerto commented 7 years ago

Please read JSON spec (http://json.org/). It defines number without quotation marks. Also, we wouldn't be consistent with postgres.

euler=# create table foo (a numeric(5,2));
CREATE TABLE
euler=# insert into foo values(1.23),(4.56),(7.89);
INSERT 0 3
euler=# select row_to_json(row(a)) from foo;
 row_to_json 
-------------
 {"f1":1.23}
 {"f1":4.56}
 {"f1":7.89}
(3 rows)
rcoup commented 7 years ago

Oh, I entirely understand that regular numbers aren't quoted in JSON.

Doing some more testing it seems the text outputs of numerics do have the correct precision & scale, so it's (reasonably) up to the JSON parser how they're interpreted from text back into numbers. 👍

eg.

# set extra_float_digits=3;
# create table x (id int primary key, a double precision, b numeric (30,20));
# insert into x values(10, '0.1'::float8*'0.1'::float8, '0.1'::numeric*'0.1'::numeric);
# select * from x;
 id |           a           |            b
----+-----------------------+-------------------------
 10 | 0.0100000000000000019 |  0.01000000000000000000

produces

{
    "change": [
        {
            "kind": "insert",
            "schema": "public",
            "table": "x",
            "columnnames": ["id", "a", "b"],
            "columntypes": ["integer", "double precision", "numeric(30,20)"],
            "columnvalues": [10, 0.01, 0.01000000000000000000]
        }
    ]
}