Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
323a87b5
Commit
323a87b5
authored
Jun 28, 2019
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-19888 Add abstract class Item_json_func
parent
cff7cf15
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
123 additions
and
73 deletions
+123
-73
sql/item_jsonfunc.cc
sql/item_jsonfunc.cc
+45
-50
sql/item_jsonfunc.h
sql/item_jsonfunc.h
+78
-23
No files found.
sql/item_jsonfunc.cc
View file @
323a87b5
...
...
@@ -439,7 +439,17 @@ bool Item_func_json_value::fix_length_and_dec()
{
collation
.
set
(
args
[
0
]
->
collation
);
max_length
=
args
[
0
]
->
max_length
;
path
.
set_constant_flag
(
args
[
1
]
->
const_item
());
set_constant_flag
(
args
[
1
]
->
const_item
());
maybe_null
=
1
;
return
FALSE
;
}
bool
Item_func_json_query
::
fix_length_and_dec
()
{
collation
.
set
(
args
[
0
]
->
collation
);
max_length
=
args
[
0
]
->
max_length
;
set_constant_flag
(
args
[
1
]
->
const_item
());
maybe_null
=
1
;
return
FALSE
;
}
...
...
@@ -449,115 +459,100 @@ bool Item_func_json_value::fix_length_and_dec()
Returns NULL, not an error if the found value
is not a scalar.
*/
String
*
Item_func_json_value
::
val_str
(
String
*
str
)
bool
Json_path_extractor
::
extract
(
String
*
str
,
Item
*
item_js
,
Item
*
item_jp
,
CHARSET_INFO
*
cs
)
{
json_engine_t
je
;
String
*
js
=
args
[
0
]
->
val_json
(
&
tmp_js
);
String
*
js
=
item_js
->
val_json
(
&
tmp_js
);
int
error
=
0
;
uint
array_counters
[
JSON_DEPTH_LIMIT
];
if
(
!
pa
th
.
pa
rsed
)
if
(
!
parsed
)
{
String
*
s_p
=
args
[
1
]
->
val_str
(
&
tmp_path
);
String
*
s_p
=
item_jp
->
val_str
(
&
tmp_path
);
if
(
s_p
&&
json_path_setup
(
&
p
ath
.
p
,
s_p
->
charset
(),
(
const
uchar
*
)
s_p
->
ptr
(),
json_path_setup
(
&
p
,
s_p
->
charset
(),
(
const
uchar
*
)
s_p
->
ptr
(),
(
const
uchar
*
)
s_p
->
ptr
()
+
s_p
->
length
()))
goto
err_return
;
pa
th
.
parsed
=
path
.
constant
;
return
true
;
pa
rsed
=
constant
;
}
if
((
null_value
=
args
[
0
]
->
null_value
||
args
[
1
]
->
null_value
))
return
NULL
;
json_scan_start
(
&
je
,
js
->
charset
(),(
const
uchar
*
)
js
->
ptr
(),
(
const
uchar
*
)
js
->
ptr
()
+
js
->
length
());
if
(
item_js
->
null_value
||
item_jp
->
null_value
)
return
true
;
Json_engine_scan
je
(
*
js
);
str
->
length
(
0
);
str
->
set_charset
(
c
ollation
.
collation
);
str
->
set_charset
(
c
s
);
path
.
cur_step
=
path
.
p
.
steps
;
cur_step
=
p
.
steps
;
continue_search:
if
(
json_find_path
(
&
je
,
&
path
.
p
,
&
path
.
cur_step
,
array_counters
))
{
if
(
je
.
s
.
error
)
goto
err_return
;
null_value
=
1
;
return
0
;
}
if
(
json_find_path
(
&
je
,
&
p
,
&
cur_step
,
array_counters
))
return
true
;
if
(
json_read_value
(
&
je
))
goto
err_return
;
return
true
;
if
(
unlikely
(
check_and_get_value
(
&
je
,
str
,
&
error
)))
{
if
(
error
)
goto
err_return
;
return
true
;
goto
continue_search
;
}
return
str
;
err_return:
null_value
=
1
;
return
0
;
return
false
;
}
bool
Item_func_json_value
::
check_and_get_value
(
json_engine_t
*
je
,
String
*
res
,
int
*
error
)
bool
Json_engine_scan
::
check_and_get_value_scalar
(
String
*
res
,
int
*
error
)
{
CHARSET_INFO
*
json_cs
;
const
uchar
*
js
;
uint
js_len
;
if
(
!
json_value_scalar
(
je
))
if
(
!
json_value_scalar
(
this
))
{
/* We only look for scalar values! */
if
(
json_skip_level
(
je
)
||
json_scan_next
(
je
))
if
(
json_skip_level
(
this
)
||
json_scan_next
(
this
))
*
error
=
1
;
return
true
;
}
if
(
je
->
value_type
==
JSON_VALUE_TRUE
||
je
->
value_type
==
JSON_VALUE_FALSE
)
if
(
value_type
==
JSON_VALUE_TRUE
||
value_type
==
JSON_VALUE_FALSE
)
{
json_cs
=
&
my_charset_utf8mb4_bin
;
js
=
(
const
uchar
*
)
((
je
->
value_type
==
JSON_VALUE_TRUE
)
?
"1"
:
"0"
);
js
=
(
const
uchar
*
)
((
value_type
==
JSON_VALUE_TRUE
)
?
"1"
:
"0"
);
js_len
=
1
;
}
else
{
json_cs
=
je
->
s
.
cs
;
js
=
je
->
value
;
js_len
=
je
->
value_len
;
json_cs
=
s
.
cs
;
js
=
value
;
js_len
=
value_len
;
}
return
st_append_json
(
res
,
json_cs
,
js
,
js_len
);
return
st_append_json
(
res
,
json_cs
,
js
,
js_len
);
}
bool
Item_func_json_query
::
check_and_get_value
(
json_engine_t
*
je
,
String
*
res
,
int
*
error
)
bool
Json_engine_scan
::
check_and_get_value_complex
(
String
*
res
,
int
*
error
)
{
const
uchar
*
value
;
if
(
json_value_scalar
(
je
))
if
(
json_value_scalar
(
this
))
{
/* We skip scalar values. */
if
(
json_scan_next
(
je
))
if
(
json_scan_next
(
this
))
*
error
=
1
;
return
true
;
}
value
=
je
->
value
;
if
(
json_skip_level
(
je
))
const
uchar
*
tmp_value
=
value
;
if
(
json_skip_level
(
this
))
{
*
error
=
1
;
return
true
;
}
res
->
set
((
const
char
*
)
je
->
value
,
(
uint32
)(
je
->
s
.
c_str
-
value
),
je
->
s
.
cs
);
res
->
set
((
const
char
*
)
value
,
(
uint32
)(
s
.
c_str
-
tmp_value
),
s
.
cs
);
return
false
;
}
...
...
sql/item_jsonfunc.h
View file @
323a87b5
...
...
@@ -40,6 +40,33 @@ class json_path_with_flags
};
class
Json_engine_scan
:
public
json_engine_t
{
public:
Json_engine_scan
(
CHARSET_INFO
*
i_cs
,
const
uchar
*
str
,
const
uchar
*
end
)
{
json_scan_start
(
this
,
i_cs
,
str
,
end
);
}
Json_engine_scan
(
const
String
&
str
)
:
Json_engine_scan
(
str
.
charset
(),
(
const
uchar
*
)
str
.
ptr
(),
(
const
uchar
*
)
str
.
end
())
{
}
bool
check_and_get_value_scalar
(
String
*
res
,
int
*
error
);
bool
check_and_get_value_complex
(
String
*
res
,
int
*
error
);
};
class
Json_path_extractor
:
public
json_path_with_flags
{
protected:
String
tmp_js
,
tmp_path
;
virtual
~
Json_path_extractor
()
{
}
virtual
bool
check_and_get_value
(
Json_engine_scan
*
je
,
String
*
to
,
int
*
error
)
=
0
;
bool
extract
(
String
*
to
,
Item
*
js
,
Item
*
jp
,
CHARSET_INFO
*
cs
);
};
class
Item_func_json_valid
:
public
Item_bool_func
{
protected:
...
...
@@ -78,32 +105,65 @@ class Item_func_json_exists: public Item_bool_func
};
class
Item_func_json_value
:
public
Item_str_func
class
Item_json_func
:
public
Item_str_func
{
public:
Item_json_func
(
THD
*
thd
)
:
Item_str_func
(
thd
)
{
}
Item_json_func
(
THD
*
thd
,
Item
*
a
)
:
Item_str_func
(
thd
,
a
)
{
}
Item_json_func
(
THD
*
thd
,
Item
*
a
,
Item
*
b
)
:
Item_str_func
(
thd
,
a
,
b
)
{
}
Item_json_func
(
THD
*
thd
,
List
<
Item
>
&
list
)
:
Item_str_func
(
thd
,
list
)
{
}
bool
is_json_type
()
{
return
true
;
}
};
class
Item_func_json_value
:
public
Item_str_func
,
public
Json_path_extractor
{
protected:
json_path_with_flags
path
;
String
tmp_js
,
tmp_path
;
public:
Item_func_json_value
(
THD
*
thd
,
Item
*
js
,
Item
*
i_path
)
:
Item_str_func
(
thd
,
js
,
i_path
)
{}
const
char
*
func_name
()
const
{
return
"json_value"
;
}
bool
fix_length_and_dec
();
String
*
val_str
(
String
*
);
virtual
bool
check_and_get_value
(
json_engine_t
*
je
,
String
*
res
,
int
*
error
);
String
*
val_str
(
String
*
to
)
{
null_value
=
Json_path_extractor
::
extract
(
to
,
args
[
0
],
args
[
1
],
collation
.
collation
);
return
null_value
?
NULL
:
to
;
}
bool
check_and_get_value
(
Json_engine_scan
*
je
,
String
*
res
,
int
*
error
)
override
{
return
je
->
check_and_get_value_scalar
(
res
,
error
);
}
Item
*
get_copy
(
THD
*
thd
)
{
return
get_item_copy
<
Item_func_json_value
>
(
thd
,
this
);
}
};
class
Item_func_json_query
:
public
Item_func_json_value
class
Item_func_json_query
:
public
Item_json_func
,
public
Json_path_extractor
{
public:
Item_func_json_query
(
THD
*
thd
,
Item
*
js
,
Item
*
i_path
)
:
Item_func_json_value
(
thd
,
js
,
i_path
)
{}
bool
is_json_type
()
{
return
true
;
}
Item_json_func
(
thd
,
js
,
i_path
)
{}
const
char
*
func_name
()
const
{
return
"json_query"
;
}
bool
check_and_get_value
(
json_engine_t
*
je
,
String
*
res
,
int
*
error
);
bool
fix_length_and_dec
();
String
*
val_str
(
String
*
to
)
{
null_value
=
Json_path_extractor
::
extract
(
to
,
args
[
0
],
args
[
1
],
collation
.
collation
);
return
null_value
?
NULL
:
to
;
}
bool
check_and_get_value
(
Json_engine_scan
*
je
,
String
*
res
,
int
*
error
)
override
{
return
je
->
check_and_get_value_complex
(
res
,
error
);
}
Item
*
get_copy
(
THD
*
thd
)
{
return
get_item_copy
<
Item_func_json_query
>
(
thd
,
this
);
}
};
...
...
@@ -139,18 +199,17 @@ class Item_func_json_unquote: public Item_str_func
};
class
Item_json_str_multipath
:
public
Item_
str
_func
class
Item_json_str_multipath
:
public
Item_
json
_func
{
protected:
json_path_with_flags
*
paths
;
String
*
tmp_paths
;
public:
Item_json_str_multipath
(
THD
*
thd
,
List
<
Item
>
&
list
)
:
Item_
str
_func
(
thd
,
list
),
tmp_paths
(
0
)
{}
Item_
json
_func
(
thd
,
list
),
tmp_paths
(
0
)
{}
bool
fix_fields
(
THD
*
thd
,
Item
**
ref
);
void
cleanup
();
virtual
uint
get_n_paths
()
const
=
0
;
bool
is_json_type
()
{
return
true
;
}
};
...
...
@@ -217,18 +276,17 @@ class Item_func_json_contains_path: public Item_bool_func
};
class
Item_func_json_array
:
public
Item_
str
_func
class
Item_func_json_array
:
public
Item_
json
_func
{
protected:
String
tmp_val
;
ulong
result_limit
;
public:
Item_func_json_array
(
THD
*
thd
)
:
Item_
str
_func
(
thd
)
{}
Item_
json
_func
(
thd
)
{}
Item_func_json_array
(
THD
*
thd
,
List
<
Item
>
&
list
)
:
Item_
str
_func
(
thd
,
list
)
{}
Item_
json
_func
(
thd
,
list
)
{}
String
*
val_str
(
String
*
);
bool
is_json_type
()
{
return
true
;
}
bool
fix_length_and_dec
();
const
char
*
func_name
()
const
{
return
"json_array"
;
}
Item
*
get_copy
(
THD
*
thd
)
...
...
@@ -273,7 +331,6 @@ class Item_func_json_object: public Item_func_json_array
Item_func_json_object
(
THD
*
thd
,
List
<
Item
>
&
list
)
:
Item_func_json_array
(
thd
,
list
)
{}
String
*
val_str
(
String
*
);
bool
is_json_type
()
{
return
true
;
}
const
char
*
func_name
()
const
{
return
"json_object"
;
}
Item
*
get_copy
(
THD
*
thd
)
{
return
get_item_copy
<
Item_func_json_object
>
(
thd
,
this
);
}
...
...
@@ -288,7 +345,6 @@ class Item_func_json_merge: public Item_func_json_array
Item_func_json_merge
(
THD
*
thd
,
List
<
Item
>
&
list
)
:
Item_func_json_array
(
thd
,
list
)
{}
String
*
val_str
(
String
*
);
bool
is_json_type
()
{
return
true
;
}
const
char
*
func_name
()
const
{
return
"json_merge_preserve"
;
}
Item
*
get_copy
(
THD
*
thd
)
{
return
get_item_copy
<
Item_func_json_merge
>
(
thd
,
this
);
}
...
...
@@ -439,7 +495,7 @@ class Item_func_json_search: public Item_json_str_multipath
};
class
Item_func_json_format
:
public
Item_
str
_func
class
Item_func_json_format
:
public
Item_
json
_func
{
public:
enum
formats
...
...
@@ -454,15 +510,14 @@ class Item_func_json_format: public Item_str_func
String
tmp_js
;
public:
Item_func_json_format
(
THD
*
thd
,
Item
*
js
,
formats
format
)
:
Item_
str
_func
(
thd
,
js
),
fmt
(
format
)
{}
Item_
json
_func
(
thd
,
js
),
fmt
(
format
)
{}
Item_func_json_format
(
THD
*
thd
,
List
<
Item
>
&
list
)
:
Item_
str
_func
(
thd
,
list
),
fmt
(
DETAILED
)
{}
Item_
json
_func
(
thd
,
list
),
fmt
(
DETAILED
)
{}
const
char
*
func_name
()
const
;
bool
fix_length_and_dec
();
String
*
val_str
(
String
*
str
);
String
*
val_json
(
String
*
str
);
bool
is_json_type
()
{
return
true
;
}
Item
*
get_copy
(
THD
*
thd
)
{
return
get_item_copy
<
Item_func_json_format
>
(
thd
,
this
);
}
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment