Re: pgsql: Add more SQL/JSON constructor functions
jian he <jian.universality@gmail.com>
Attachments
- v1-0001-hanlde-types-that-have-type-modifier-for-json-on-.patch (application/x-patch) patch v1-0001
- scratch169.sql (application/sql)
On Sun, Jun 30, 2024 at 2:24 AM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
>
> TBH I'm not super clear on why we decide on explicit or implicit cast
> based on presence of a typmod. Why isn't it better to always use an
> implicit one?
>
I am using an example to explain it.
SELECT JSON_SERIALIZE(JSON('{ "a" : 1 } '));
we cannot directly use implicit cast from json to text in
{coerceJsonFuncExpr, coerce_to_target_type}
because function calls:
coerceJsonFuncExpr->coerce_to_target_type->can_coerce_type
->find_coercion_pathway
will look up pg_cast entries.
but we don't have text & json implicit cast entries, we will fail at:
````
if (!res && report_error)
ereport(ERROR,
errcode(ERRCODE_CANNOT_COERCE),
errmsg("cannot cast type %s to %s",
format_type_be(exprtype),
format_type_be(returning->typid)),
parser_coercion_errposition(pstate, location, expr));
````
Most of the cast uses explicit cast, which is what we previously did,
then in this thread, we found out for the returning type typmod(
(varchar, or varchar's domain)
We need to first cast the expression to text then text to varchar via
implicit cast.
To trap the error:
for example: SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING varchar(2);
also see the comment:
https://git.postgresql.org/cgit/postgresql.git/commit/?id=c2d93c3802b205d135d1ae1d7ac167d74e08a274
+ /*
+ * Convert the source expression to text, because coerceJsonFuncExpr()
+ * will create an implicit cast to the RETURNING types with typmod and
+ * there are no implicit casts from json(b) to such types. For domains,
+ * the base type's typmod will be considered, so do so here too.
+ */
In general, I think implicit cast here is an exception.
overall I come up with following logic:
-----------------
int32 baseTypmod = -1;
if (returning->typmod < 0)
(void) getBaseTypeAndTypmod(returning->typid, &baseTypmod);
else
baseTypmod = returning->typmod;
res = coerce_to_target_type(pstate, expr, exprtype,
returning->typid, baseTypmod,
baseTypmod > 0 ? COERCION_IMPLICIT :
COERCION_EXPLICIT,
baseTypmod > 0 ? COERCE_IMPLICIT_CAST :
COERCE_EXPLICIT_CAST,
location);
-----------------
By the same way we are dealing with varchar,
I came up with a verbose patch for transformJsonBehavior,
which can cope with all the corner cases of bit and varbit data type.
I also attached a test sql file (scratch169.sql) for it.
some examples:
--fail
SELECT JSON_VALUE(jsonb '"111a"', '$' RETURNING bit(3) default '1111'
on error);
--ok
SELECT JSON_VALUE(jsonb '"111a"', '$' RETURNING bit(3) default '111' on error);
--ok
SELECT JSON_VALUE(jsonb '"111a"', '$' RETURNING bit(3) default 32 on error);
makeJsonConstructorExpr we called (void)
getBaseTypeAndTypmod(returning->typid, &baseTypmod);
later in coerceJsonFuncExpr
we may also call (void) getBaseTypeAndTypmod(returning->typid, &baseTypmod);
maybe we can do some refactoring.
Commits
-
SQL/JSON: Avoid initializing unnecessary ON ERROR / ON EMPTY steps
- 77aebe9a8d3c 17.0 landed
- dd8bea88abf4 18.0 landed
- 3a97460970f3 18.0 landed
- e4e27976a687 17.0 landed
-
SQL/JSON: Fix default ON ERROR behavior for JSON_TABLE
- 446d5ad7ae7d 17.0 landed
- bbd4c058a89b 18.0 landed
- 5067c230b8ee 17.0 landed
- 565caaa79af9 18.0 landed
-
SQL/JSON: Fix JSON_TABLE() column deparsing
- cd680b39211c 17.0 landed
- ee75a03f37fc 18.0 landed
- c88ce386c4d7 17.0 landed
- 68222851d5a8 18.0 landed
-
Update comment about ExprState.escontext
- fe323438140f 17.0 landed
- 3422f5f93fcf 18.0 landed
-
SQL/JSON: Fix casting for integer EXISTS columns in JSON_TABLE
- f95c5090d975 17.0 landed
- 7f56eaff2fb0 18.0 landed
-
SQL/JSON: Some fixes to JsonBehavior expression casting
- 847ee701bd3a 17.0 landed
- 74c96699be3f 18.0 landed
-
SQL/JSON: Remove useless code in ExecInitJsonExpr()
- 6f9a62b454e8 18.0 landed
- 8a1a4087bd5f 17.0 landed
-
SQL/JSON: Respect OMIT QUOTES when RETURNING domains over jsonb
- 3c3ccd4ca801 17.0 landed
- 4fc6a555606d 18.0 landed
-
SQL/JSON: Improve error-handling of JsonBehavior expressions
- d1dc4ae5608d 17.0 landed
- 231b7d670b21 18.0 landed
-
SQL/JSON: Fix error-handling of some JsonBehavior expressions
- 79fa052e7880 17.0 landed
- 63e6c5f4a2ee 18.0 landed
-
SQL/JSON: Rethink c2d93c3802b
- 86d33987e8b0 18.0 landed
- 2177306a6413 17.0 landed
-
SQL/JSON: Always coerce JsonExpr result at runtime
- 716bd12d22c5 17.0 landed
-
SQL/JSON: Fix coercion of constructor outputs to types with typmod
- c2d93c3802b2 17.0 landed