[MDEV-25822] JSON_TABLE: default values should allow non-string literals Created: 2021-05-30  Updated: 2023-11-06

Status: In Review
Project: MariaDB Server
Component/s: JSON
Affects Version/s: 10.6
Fix Version/s: 10.6

Type: Bug Priority: Critical
Reporter: Sergei Petrunia Assignee: Sergei Petrunia
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Filing this for https://www.mail-archive.com/maria-developers@lists.launchpad.net/msg12296.html

At the moment MariaDB requires that the values in DEFAULT clauses are quoted.
Example:

select * 
from 
  json_table(
    '{"intval": 1000}',
    '$' columns( 
                 col1 int path '$.intval_'
                    default '100' on empty
               )
   ) as T;

here, "100" must be quoted, otherwise one gets a parse error. However, the quoted value is interpreted as an SQL literal. This looks puzzling.

MySQL-8 also requires that the default value is quoted, but they have a (very odd) reason for it: they interpret the default value as JSON:

https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/json-table-functions.html
says:

DEFAULT json_string ON EMPTY: the provided json_string is parsed as JSON, as
long as it is valid, and stored instead of the missing value. Column type
rules also apply to the default value.

I am not sure why MySQL chose to do this. Looking into the SQL Standard, one
can see:

<JSON table regular column definition> ::=
<column name> <data type>
      [ PATH <JSON table column path specification> ]
      [ <JSON table column empty behavior> ON EMPTY ]
      [ <JSON table column error behavior> ON ERROR ]
 
<JSON table column empty behavior> ::=
    ERROR
  | NULL
  | DEFAULT <value expression>

This doesn't say whether the <value expression> should be interepreted as JSON
or just as a value. But one can find this passage:

Without Feature T826, "General value expression in ON ERROR or ON EMPTY 
clauses", the <value
expression> contained in <JSON table column empty behavior> or <JSON table 
column error behavior>
contained in a <JSON table regular column definition> JTRCD shall be a 
<literal> that can be cast to the
data type specified by the <data type> contained in JTRCD without raising an 
exception condition
according to the General Rules of Subclause 6.13, "<cast specification>".

The important part is:

... shall be a <literal> that can be cast to the data type specified ...

which means it is not JSON. It is just a literal, and literal can be a string
literal (in quotes, 'string') or an integer literal (without quotes) or other
kind of literal.

Btw, Oracle Database allows non-string literals in the default clause:
https://dbfiddle.uk/?rdbms=oracle_18&fiddle=9af7e43ede77ee285e1a65f1f419d3bd



 Comments   
Comment by Sergei Petrunia [ 2021-05-30 ]

A patch by Alexey: https://github.com/MariaDB/server/commit/9c518e4cc9b0569cae2daa5a4024e209293eca45

Comment by Sergei Petrunia [ 2021-06-08 ]

Review input: https://lists.launchpad.net/maria-developers/msg12763.html

Comment by Alexey Botchkov [ 2021-06-16 ]

https://github.com/MariaDB/server/commit/8dae7ee02f98e71e9352d73d1da235fd4128d076

Generated at Thu Feb 08 09:40:40 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.