← Back to team overview

maria-developers team mailing list archive

MDEV-25875: RE 02469b: MDEV-17399 JSON_TABLE Accept JSON values for the JSON fields

 

Hi Alexey,

This is review input re
https://github.com/MariaDB/server/commit/02469bdead5753eccb5d70c98a158a07027f4eb2.

First, our workflow dictates that this patch should have its own MDEV entry.
I've filed it https://jira.mariadb.org/browse/MDEV-25875.
Please use it in commit descriptions.

== Updates mixed with another patch ==

The patch has .result changes like:

> @@ -551,10 +551,12 @@ JSON_TABLE('{}', '$' COLUMNS (x INT PATH '$.x' DEFAULT NULL ON ERROR)) jt;
>  ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NULL ON ERROR)) jt' at line 2
>  SELECT * FROM
>  JSON_TABLE('{}', '$' COLUMNS (x INT PATH '$.x' DEFAULT 0 ON EMPTY)) jt;
> -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '0 ON EMPTY)) jt' at line 2
> +x
> +0
>  SELECT * FROM
>  JSON_TABLE('{}', '$' COLUMNS (x INT PATH '$.x' DEFAULT 0 ON ERROR)) jt;
> -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '0 ON ERROR)) jt' at line 2
> +x
> +NULL
>  SELECT * FROM
>  JSON_TABLE('{}', '$' COLUMNS (x DATE
>  PATH '$.x'

These are obviously from another patch (the one about "accepting non-string
literals as default").  Please move them to that patch.

== Comments ==

> @@ -377,6 +378,25 @@ static void store_json_in_field(Field *f, const json_engine_t *je)
>  }
>  
>  
> +static int store_json_in_json(Field *f, json_engine_t *je)
> +{
Please add a comment for the function. Something like

"Store the current JSON element pointed by je into field f, as a separate JSON
document" 

The name "store_json_in_json" doesn't look good to me.
Do you think store_element_as_json_doc() would be better?

> +  const uchar *from= je->value_begin;
> +  const uchar *to;
> +
> +  if (json_value_scalar(je))
> +    to= je->value_end;
> +  else
> +  {
> +    int error;
> +    if ((error= json_skip_level(je)))
> +      return error;
> +    to= je->s.c_str;
> +  }
> +  f->store((const char *) from, (uint32) (to - from), je->s.cs);
> +  return 0;
> +}
> +
> +
>  bool Json_table_nested_path::check_error(const char *str)
>  {
>    if (m_engine.s.error)
> @@ -541,7 +561,12 @@ int ha_json_table::fill_column_values(THD *thd, uchar * buf, uchar *pos)
>            }
>            else
>            {
> -            if (!(error= !json_value_scalar(&je)))
> +            if (jc->m_format_json)
> +            {
> +              if (!(error= store_json_in_json(*f, &je)))
> +                error= er_handler.errors;
Can there be a case when this assignment assigns any value other than 0? 
(My logic - er_handler.errors already had some error status, why did we call
store_json_in_json?  If there was an error inside store_json_in_json, we do not
get to this assignment, as store_json_in_json() returned non-zero error.  Is
this correct?)

> +            }
> +            else if (!(error= !json_value_scalar(&je)))
>              {
>                store_json_in_field(*f, &je);
>                error= er_handler.errors;
> @@ -868,6 +893,10 @@ int Json_table_column::set(THD *thd, enum_type ctype, const LEX_CSTRING &path)
>      anctual content. Not sure though if we should.
>    */
>    m_path.s.c_str= (const uchar *) path.str;
> +
> +  if (ctype == PATH)
> +    m_format_json= m_field->type_handler() == &type_handler_json_longtext;

This will probably cause warnings on some compiler. Please wrap into
"MY_TEST(...)" or just brackets, "z= (x == y)".

== A discrepancy between this and MySQL ==
I've found this case:

select * from
  json_table('{"foo": null}',
             '$' columns( jscol json path '$.foo')
             ) as T;

with the above patch, it produces a JSON null value:
+-------+
| jscol |
+-------+
| null  |
+-------+

while in MySQL-8 it produces an SQL NULL:
+-------+
| jscol |
+-------+
| NULL  |
+-------+

I'm not yet sure what we should do about this. Any thoughts?

BR
 Sergei
-- 
Sergei Petrunia, Software Developer
MariaDB Corporation | Skype: sergefp | Blog: http://petrunia.net




Follow ups