Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 92c4ca5

Browse files
author
Nikita Glukhov
committed
Map PG jsonb to SQL JSON type
1 parent 12f0169 commit 92c4ca5

File tree

9 files changed

+233
-1
lines changed

9 files changed

+233
-1
lines changed

doc/src/sgml/config.sgml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9349,6 +9349,24 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
93499349
</listitem>
93509350
</varlistentry>
93519351

9352+
<varlistentry id="guc-sql-json" xreflabel="sql_json">
9353+
<term><varname>sql_json</varname> (<type>enum</type>)
9354+
<indexterm><primary>json</primary></indexterm>
9355+
<indexterm><primary>jsonb</primary></indexterm>
9356+
<indexterm>
9357+
<primary><varname>sql_json</varname> configuration parameter</primary>
9358+
</indexterm>
9359+
</term>
9360+
<listitem>
9361+
<para>
9362+
Valid values are <literal>json</literal> and <literal>jsonb</literal>.
9363+
Specifies what <productname>PostgreSQL</productname> type is used
9364+
as an implementation of SQL type <type>JSON</type>.
9365+
SQL type <type>JSON TEXT</type> is always mapped to
9366+
<productname>PostgreSQL</productname> type <type>json</type>.
9367+
</para>
9368+
</listitem>
9369+
</varlistentry>
93529370
</variablelist>
93539371
</sect2>
93549372
</sect1>

src/backend/parser/gram.y

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#include "storage/lmgr.h"
6464
#include "utils/date.h"
6565
#include "utils/datetime.h"
66+
#include "utils/jsonb.h"
6667
#include "utils/numeric.h"
6768
#include "utils/xml.h"
6869

@@ -12983,8 +12984,14 @@ interval_second:
1298312984
}
1298412985
;
1298512986

12987+
/* Mapping of PG jsonb types to SQL/JSON JSON type */
1298612988
JsonType:
1298712989
JSON
12990+
{
12991+
$$ = SystemTypeName(SQLJSON_TYPE_NAME());
12992+
$$->location = @1;
12993+
}
12994+
| JSON TEXT_P
1298812995
{
1298912996
$$ = SystemTypeName("json");
1299012997
$$->location = @1;

src/backend/utils/adt/format_type.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "catalog/pg_type.h"
2323
#include "mb/pg_wchar.h"
2424
#include "utils/builtins.h"
25+
#include "utils/jsonb.h"
2526
#include "utils/lsyscache.h"
2627
#include "utils/numeric.h"
2728
#include "utils/syscache.h"
@@ -296,7 +297,11 @@ format_type_extended(Oid type_oid, int32 typemod, bits16 flags)
296297
break;
297298

298299
case JSONOID:
299-
buf = pstrdup("json");
300+
buf = pstrdup(SQLJSON_TYPE_IS_JSONB() ? "json text" : "json");
301+
break;
302+
303+
case JSONBOID:
304+
buf = pstrdup(SQLJSON_TYPE_IS_JSONB() ? "json" : "jsonb");
300305
break;
301306
}
302307

src/backend/utils/adt/jsonb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ static JsonbParseState *clone_parse_state(JsonbParseState *state);
6969
static char *JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent);
7070
static void add_indent(StringInfo out, bool indent, int level);
7171

72+
int sql_json_type; /* GUC for mapping jsonb to SQL/JSON JSON */
73+
7274
/*
7375
* jsonb type input function
7476
*/

src/backend/utils/misc/guc.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
#include "utils/bytea.h"
9191
#include "utils/float.h"
9292
#include "utils/guc_tables.h"
93+
#include "utils/jsonb.h"
9394
#include "utils/memutils.h"
9495
#include "utils/pg_locale.h"
9596
#include "utils/pg_lsn.h"
@@ -498,6 +499,12 @@ static struct config_enum_entry shared_memory_options[] = {
498499
{NULL, 0, false}
499500
};
500501

502+
const struct config_enum_entry sql_json_type_info[] = {
503+
{"json", SQLJSON_TYPE_JSON, false},
504+
{"jsonb", SQLJSON_TYPE_JSONB, false},
505+
{NULL, 0, false}
506+
};
507+
501508
/*
502509
* Options for enum values stored in other modules
503510
*/
@@ -4762,6 +4769,18 @@ static struct config_enum ConfigureNamesEnum[] =
47624769
NULL, NULL, NULL
47634770
},
47644771

4772+
{
4773+
{"sql_json", PGC_USERSET, COMPAT_OPTIONS_CLIENT,
4774+
gettext_noop("Sets what PostgreSQL type to use as an implementaion of SQL JSON type."),
4775+
gettext_noop("When turned on, jsonb type is mapped to SQL JSON type, "
4776+
"json type is mapped to JSON TEXT type.")
4777+
},
4778+
&sql_json_type,
4779+
SQLJSON_TYPE_JSON,
4780+
sql_json_type_info,
4781+
NULL, NULL, NULL
4782+
},
4783+
47654784
/* End-of-list marker */
47664785
{
47674786
{NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL

src/backend/utils/misc/postgresql.conf.sample

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,7 @@
746746
# - Other Platforms and Clients -
747747

748748
#transform_null_equals = off
749+
#sql_json = json # jsonb
749750

750751

751752
#------------------------------------------------------------------------------

src/include/utils/jsonb.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,4 +439,16 @@ extern Datum jsonb_build_object_worker(int nargs, Datum *args, bool *nulls,
439439
extern Datum jsonb_build_array_worker(int nargs, Datum *args, bool *nulls,
440440
Oid *types, bool absent_on_null);
441441

442+
typedef enum SqlJsonType
443+
{
444+
SQLJSON_TYPE_JSON = 0,
445+
SQLJSON_TYPE_JSONB = 1
446+
} SqlJsonType;
447+
448+
#define SQLJSON_TYPE_IS_JSONB() (sql_json_type == SQLJSON_TYPE_JSONB)
449+
#define SQLJSON_TYPE_OID() (SQLJSON_TYPE_IS_JSONB() ? JSONBOID : JSONOID)
450+
#define SQLJSON_TYPE_NAME() (SQLJSON_TYPE_IS_JSONB() ? "jsonb" : "json")
451+
452+
extern int sql_json_type; /* GUC */
453+
442454
#endif /* __JSONB_H__ */

src/test/regress/expected/jsonb.out

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5014,3 +5014,133 @@ select '12345.0000000000000000000000000000000000000000000005'::jsonb::int8;
50145014
12345
50155015
(1 row)
50165016

5017+
-- test mapping of jsonb to SQL/JSON JSON type
5018+
select json(' { "aa": 1, "b" : 2 }');
5019+
json
5020+
-----------------------
5021+
{ "aa": 1, "b" : 2 }
5022+
(1 row)
5023+
5024+
select json ' { "aa": 1, "b" : 2 }';
5025+
json
5026+
-----------------------
5027+
{ "aa": 1, "b" : 2 }
5028+
(1 row)
5029+
5030+
select json text ' { "aa": 1, "b" : 2 }';
5031+
json
5032+
-----------------------
5033+
{ "aa": 1, "b" : 2 }
5034+
(1 row)
5035+
5036+
create table test_json_as_json (js json, jb jsonb);
5037+
\d test_json_as_json
5038+
Table "public.test_json_as_json"
5039+
Column | Type | Collation | Nullable | Default
5040+
--------+-------+-----------+----------+---------
5041+
js | json | | |
5042+
jb | jsonb | | |
5043+
5044+
set sql_json = jsonb;
5045+
select json(' { "aa": 1, "b" : 2 }');
5046+
jsonb
5047+
-------------------
5048+
{"b": 2, "aa": 1}
5049+
(1 row)
5050+
5051+
select json ' { "aa": 1, "b" : 2 }';
5052+
jsonb
5053+
-------------------
5054+
{"b": 2, "aa": 1}
5055+
(1 row)
5056+
5057+
select json text ' { "aa": 1, "b" : 2 }';
5058+
json
5059+
-----------------------
5060+
{ "aa": 1, "b" : 2 }
5061+
(1 row)
5062+
5063+
\d test_json_as_json
5064+
Table "public.test_json_as_json"
5065+
Column | Type | Collation | Nullable | Default
5066+
--------+-----------+-----------+----------+---------
5067+
js | json text | | |
5068+
jb | json | | |
5069+
5070+
create table test_json_as_jsonb (js json, jb jsonb, jt json text);
5071+
\d test_json_as_jsonb
5072+
Table "public.test_json_as_jsonb"
5073+
Column | Type | Collation | Nullable | Default
5074+
--------+-----------+-----------+----------+---------
5075+
js | json | | |
5076+
jb | json | | |
5077+
jt | json text | | |
5078+
5079+
insert into test_json_as_jsonb values ('{ "a" : 1 }', '{ "a" : 1 }', '{ "a" : 1 }');
5080+
select * from test_json_as_jsonb;
5081+
js | jb | jt
5082+
----------+----------+-------------
5083+
{"a": 1} | {"a": 1} | { "a" : 1 }
5084+
(1 row)
5085+
5086+
select jsonb_object_field(js, 'a') from test_json_as_jsonb;
5087+
jsonb_object_field
5088+
--------------------
5089+
1
5090+
(1 row)
5091+
5092+
select jsonb_object_field(jb, 'a') from test_json_as_jsonb;
5093+
jsonb_object_field
5094+
--------------------
5095+
1
5096+
(1 row)
5097+
5098+
select jsonb_object_field(jt, 'a') from test_json_as_jsonb;
5099+
ERROR: function jsonb_object_field(json text, unknown) does not exist
5100+
LINE 1: select jsonb_object_field(jt, 'a') from test_json_as_jsonb;
5101+
^
5102+
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
5103+
select json_object_field(jt, 'a') from test_json_as_jsonb;
5104+
json_object_field
5105+
-------------------
5106+
1
5107+
(1 row)
5108+
5109+
set sql_json = json;
5110+
\d test_json_as_jsonb
5111+
Table "public.test_json_as_jsonb"
5112+
Column | Type | Collation | Nullable | Default
5113+
--------+-------+-----------+----------+---------
5114+
js | jsonb | | |
5115+
jb | jsonb | | |
5116+
jt | json | | |
5117+
5118+
select * from test_json_as_jsonb;
5119+
js | jb | jt
5120+
----------+----------+-------------
5121+
{"a": 1} | {"a": 1} | { "a" : 1 }
5122+
(1 row)
5123+
5124+
select jsonb_object_field(js, 'a') from test_json_as_jsonb;
5125+
jsonb_object_field
5126+
--------------------
5127+
1
5128+
(1 row)
5129+
5130+
select jsonb_object_field(jb, 'a') from test_json_as_jsonb;
5131+
jsonb_object_field
5132+
--------------------
5133+
1
5134+
(1 row)
5135+
5136+
select jsonb_object_field(jt, 'a') from test_json_as_jsonb;
5137+
ERROR: function jsonb_object_field(json, unknown) does not exist
5138+
LINE 1: select jsonb_object_field(jt, 'a') from test_json_as_jsonb;
5139+
^
5140+
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
5141+
select json_object_field(jt, 'a') from test_json_as_jsonb;
5142+
json_object_field
5143+
-------------------
5144+
1
5145+
(1 row)
5146+

src/test/regress/sql/jsonb.sql

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,3 +1280,41 @@ select '12345.0000000000000000000000000000000000000000000005'::jsonb::float8;
12801280
select '12345.0000000000000000000000000000000000000000000005'::jsonb::int2;
12811281
select '12345.0000000000000000000000000000000000000000000005'::jsonb::int4;
12821282
select '12345.0000000000000000000000000000000000000000000005'::jsonb::int8;
1283+
1284+
-- test mapping of jsonb to SQL/JSON JSON type
1285+
select json(' { "aa": 1, "b" : 2 }');
1286+
select json ' { "aa": 1, "b" : 2 }';
1287+
select json text ' { "aa": 1, "b" : 2 }';
1288+
1289+
create table test_json_as_json (js json, jb jsonb);
1290+
\d test_json_as_json
1291+
1292+
set sql_json = jsonb;
1293+
1294+
select json(' { "aa": 1, "b" : 2 }');
1295+
select json ' { "aa": 1, "b" : 2 }';
1296+
select json text ' { "aa": 1, "b" : 2 }';
1297+
1298+
\d test_json_as_json
1299+
1300+
create table test_json_as_jsonb (js json, jb jsonb, jt json text);
1301+
\d test_json_as_jsonb
1302+
1303+
insert into test_json_as_jsonb values ('{ "a" : 1 }', '{ "a" : 1 }', '{ "a" : 1 }');
1304+
1305+
select * from test_json_as_jsonb;
1306+
1307+
select jsonb_object_field(js, 'a') from test_json_as_jsonb;
1308+
select jsonb_object_field(jb, 'a') from test_json_as_jsonb;
1309+
select jsonb_object_field(jt, 'a') from test_json_as_jsonb;
1310+
select json_object_field(jt, 'a') from test_json_as_jsonb;
1311+
1312+
set sql_json = json;
1313+
\d test_json_as_jsonb
1314+
1315+
select * from test_json_as_jsonb;
1316+
1317+
select jsonb_object_field(js, 'a') from test_json_as_jsonb;
1318+
select jsonb_object_field(jb, 'a') from test_json_as_jsonb;
1319+
select jsonb_object_field(jt, 'a') from test_json_as_jsonb;
1320+
select json_object_field(jt, 'a') from test_json_as_jsonb;

0 commit comments

Comments
 (0)