Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcb5d942

Browse files
committed
Improve jsonb cast error message
Initial variant of error message didn't follow style of another casting errormessages and wasn't informative. Per gripe from Robert Haas.Reviewer: Tom LaneDiscussion:https://www.postgresql.org/message-id/flat/CA%2BTgmob08StTV9yu04D0idRFNMh%2BUoyKax5Otvrix7rEZC8rMw%40mail.gmail.com#CA+Tgmob08StTV9yu04D0idRFNMh+UoyKax5Otvrix7rEZC8rMw@mail.gmail.com
1 parentc63913c commitcb5d942

File tree

2 files changed

+51
-28
lines changed

2 files changed

+51
-28
lines changed

‎src/backend/utils/adt/jsonb.c

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,15 +1857,19 @@ jsonb_object_agg_finalfn(PG_FUNCTION_ARGS)
18571857
/*
18581858
* Extract scalar value from raw-scalar pseudo-array jsonb.
18591859
*/
1860-
staticJsonbValue*
1860+
staticbool
18611861
JsonbExtractScalar(JsonbContainer*jbc,JsonbValue*res)
18621862
{
18631863
JsonbIterator*it;
18641864
JsonbIteratorTokentokPG_USED_FOR_ASSERTS_ONLY;
18651865
JsonbValuetmp;
18661866

18671867
if (!JsonContainerIsArray(jbc)|| !JsonContainerIsScalar(jbc))
1868-
returnNULL;
1868+
{
1869+
/* inform caller about actual type of container */
1870+
res->type= (JsonContainerIsArray(jbc)) ?jbvArray :jbvObject;
1871+
return false;
1872+
}
18691873

18701874
/*
18711875
* A root scalar is stored as an array of one element, so we get the array
@@ -1887,7 +1891,40 @@ JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
18871891
tok=JsonbIteratorNext(&it,&tmp, true);
18881892
Assert(tok==WJB_DONE);
18891893

1890-
returnres;
1894+
return true;
1895+
}
1896+
1897+
/*
1898+
* Emit correct, translatable cast error message
1899+
*/
1900+
staticvoid
1901+
cannotCastJsonbValue(enumjbvTypetype,constchar*sqltype)
1902+
{
1903+
staticconststruct
1904+
{
1905+
enumjbvTypetype;
1906+
constchar*msg;
1907+
}
1908+
messages[]=
1909+
{
1910+
{jbvNull,gettext_noop("cannot cast jsonb null to type %s") },
1911+
{jbvString,gettext_noop("cannot cast jsonb string to type %s") },
1912+
{jbvNumeric,gettext_noop("cannot cast jsonb numeric to type %s") },
1913+
{jbvBool,gettext_noop("cannot cast jsonb boolean to type %s") },
1914+
{jbvArray,gettext_noop("cannot cast jsonb array to type %s") },
1915+
{jbvObject,gettext_noop("cannot cast jsonb object to type %s") },
1916+
{jbvBinary,gettext_noop("cannot cast jsonb array or object to type %s") }
1917+
};
1918+
inti;
1919+
1920+
for(i=0;i<lengthof(messages);i++)
1921+
if (messages[i].type==type)
1922+
ereport(ERROR,
1923+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1924+
errmsg(messages[i].msg,sqltype)));
1925+
1926+
/* should be unreachable */
1927+
elog(ERROR,"unknown jsonb type: %d", (int)type);
18911928
}
18921929

18931930
Datum
@@ -1897,9 +1934,7 @@ jsonb_bool(PG_FUNCTION_ARGS)
18971934
JsonbValuev;
18981935

18991936
if (!JsonbExtractScalar(&in->root,&v)||v.type!=jbvBool)
1900-
ereport(ERROR,
1901-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1902-
errmsg("jsonb value must be boolean")));
1937+
cannotCastJsonbValue(v.type,"boolean");
19031938

19041939
PG_FREE_IF_COPY(in,0);
19051940

@@ -1914,9 +1949,7 @@ jsonb_numeric(PG_FUNCTION_ARGS)
19141949
NumericretValue;
19151950

19161951
if (!JsonbExtractScalar(&in->root,&v)||v.type!=jbvNumeric)
1917-
ereport(ERROR,
1918-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1919-
errmsg("jsonb value must be numeric")));
1952+
cannotCastJsonbValue(v.type,"numeric");
19201953

19211954
/*
19221955
* v.val.numeric points into jsonb body, so we need to make a copy to
@@ -1937,9 +1970,7 @@ jsonb_int2(PG_FUNCTION_ARGS)
19371970
DatumretValue;
19381971

19391972
if (!JsonbExtractScalar(&in->root,&v)||v.type!=jbvNumeric)
1940-
ereport(ERROR,
1941-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1942-
errmsg("jsonb value must be numeric")));
1973+
cannotCastJsonbValue(v.type,"smallint");
19431974

19441975
retValue=DirectFunctionCall1(numeric_int2,
19451976
NumericGetDatum(v.val.numeric));
@@ -1957,9 +1988,7 @@ jsonb_int4(PG_FUNCTION_ARGS)
19571988
DatumretValue;
19581989

19591990
if (!JsonbExtractScalar(&in->root,&v)||v.type!=jbvNumeric)
1960-
ereport(ERROR,
1961-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1962-
errmsg("jsonb value must be numeric")));
1991+
cannotCastJsonbValue(v.type,"integer");
19631992

19641993
retValue=DirectFunctionCall1(numeric_int4,
19651994
NumericGetDatum(v.val.numeric));
@@ -1977,9 +2006,7 @@ jsonb_int8(PG_FUNCTION_ARGS)
19772006
DatumretValue;
19782007

19792008
if (!JsonbExtractScalar(&in->root,&v)||v.type!=jbvNumeric)
1980-
ereport(ERROR,
1981-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1982-
errmsg("jsonb value must be numeric")));
2009+
cannotCastJsonbValue(v.type,"bigint");
19832010

19842011
retValue=DirectFunctionCall1(numeric_int8,
19852012
NumericGetDatum(v.val.numeric));
@@ -1997,9 +2024,7 @@ jsonb_float4(PG_FUNCTION_ARGS)
19972024
DatumretValue;
19982025

19992026
if (!JsonbExtractScalar(&in->root,&v)||v.type!=jbvNumeric)
2000-
ereport(ERROR,
2001-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2002-
errmsg("jsonb value must be numeric")));
2027+
cannotCastJsonbValue(v.type,"real");
20032028

20042029
retValue=DirectFunctionCall1(numeric_float4,
20052030
NumericGetDatum(v.val.numeric));
@@ -2017,9 +2042,7 @@ jsonb_float8(PG_FUNCTION_ARGS)
20172042
DatumretValue;
20182043

20192044
if (!JsonbExtractScalar(&in->root,&v)||v.type!=jbvNumeric)
2020-
ereport(ERROR,
2021-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2022-
errmsg("jsonb value must be numeric")));
2045+
cannotCastJsonbValue(v.type,"double precision");
20232046

20242047
retValue=DirectFunctionCall1(numeric_float8,
20252048
NumericGetDatum(v.val.numeric));

‎src/test/regress/expected/jsonb.out

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4321,31 +4321,31 @@ select 'true'::jsonb::bool;
43214321
(1 row)
43224322

43234323
select '[]'::jsonb::bool;
4324-
ERROR: jsonbvalue must be boolean
4324+
ERROR:cannot castjsonbarray to type boolean
43254325
select '1.0'::jsonb::float;
43264326
float8
43274327
--------
43284328
1
43294329
(1 row)
43304330

43314331
select '[1.0]'::jsonb::float;
4332-
ERROR: jsonbvalue must be numeric
4332+
ERROR:cannot castjsonbarray to type double precision
43334333
select '12345'::jsonb::int4;
43344334
int4
43354335
-------
43364336
12345
43374337
(1 row)
43384338

43394339
select '"hello"'::jsonb::int4;
4340-
ERROR: jsonbvalue must be numeric
4340+
ERROR:cannot castjsonbstring to type integer
43414341
select '12345'::jsonb::numeric;
43424342
numeric
43434343
---------
43444344
12345
43454345
(1 row)
43464346

43474347
select '{}'::jsonb::numeric;
4348-
ERROR: jsonbvalue must be numeric
4348+
ERROR:cannot castjsonbobject to type numeric
43494349
select '12345.05'::jsonb::numeric;
43504350
numeric
43514351
----------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp