New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mysql/json: support comparison #1893
Conversation
src/util/codec/mysql/json.rs
Outdated
TYPE_CODE_DOUBLE | TYPE_CODE_I64 => { | ||
let left_data = self.as_f64().unwrap(); | ||
let right_data = right.as_f64().unwrap(); | ||
left_data.partial_cmp(&right_data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here do we need consider precision?
src/util/codec/mysql/json.rs
Outdated
@@ -12,6 +12,7 @@ | |||
// limitations under the License. | |||
|
|||
use super::Result; | |||
use std::cmp::{Ordering, Ord, PartialEq, PartialOrd}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ord, PartialEq, PartialOrd
src/util/codec/mysql/json.rs
Outdated
@@ -31,19 +32,42 @@ const TYPE_CODE_I64: u8 = 0x09; | |||
const TYPE_CODE_DOUBLE: u8 = 0x0b; | |||
const TYPE_CODE_STRING: u8 = 0x0c; | |||
|
|||
#[allow(dead_code)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#![allow(dead_code)]
src/util/codec/mysql/json.rs
Outdated
#[allow(dead_code)] | ||
const PRECEDENCE_DATE: i32 = -6; | ||
const PRECEDENCE_BOOLEAN: i32 = -7; | ||
const PRECEDENCE_ARRAY: i32 = -8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why negative
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are copied from tidb
@andelf
src/util/codec/mysql/json.rs
Outdated
|
||
// Json implement type json used in tikv, it specifies the following | ||
// Json implements type json used in tikv, it specifies the following |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
///
src/util/codec/mysql/json.rs
Outdated
return match self.get_type_code() { | ||
TYPE_CODE_LITERAL => { | ||
let left_data = self.as_literal().unwrap(); | ||
let right_data = right.as_literal().unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will fail, use Option::None
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ref doc:
impl<T: PartialOrd> PartialOrd for Option<T>
impl<T: PartialOrd, E: PartialOrd> PartialOrd for Result<T, E>
This will give you some hint for how to implement comparison neatly. 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
address comment @andelf
src/util/codec/mysql/json.rs
Outdated
|
||
let left_data = self.as_f64(); | ||
let right_data = right.as_f64(); | ||
// tidb treat boolean as integer, but boolean is different from integer in JSON. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
treats
src/util/codec/mysql/json.rs
Outdated
} | ||
} | ||
|
||
impl Eq for Json {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eq, Ord is needless and theoretically wrong?
src/util/codec/mysql/json.rs
Outdated
(&json_bool_false, &json_bool_true), | ||
]; | ||
|
||
for (left, right) in test_cases { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for (&left, &right) in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be failed with
722 | for (&left, &right) in test_cases {
| ^-----
| ||
| |hint: to prevent move, use `ref right` or `ref mut right`
| cannot move out of borrowed content
src/util/codec/mysql/json.rs
Outdated
@@ -484,7 +613,7 @@ pub trait JsonDecoder: NumberDecoder { | |||
} | |||
|
|||
fn decode_json_item(&mut self, values_data: &[u8], data_start_position: u32) -> Result<Json> { | |||
let mut entry = vec![0;LENGTH_VALUE_ENTRY]; | |||
let mut entry = vec![0;VALUE_ENTRY_LEN]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
space ?
LGTM |
src/util/codec/mysql/json.rs
Outdated
let json_array_big = Json::from_str(r#"["a", "c"]"#).unwrap(); | ||
let json_array_small = Json::from_str(r#"["a", "b"]"#).unwrap(); | ||
let json_object = Json::from_str(r#"{"a": "b"}"#).unwrap(); | ||
let test_cases = vec![ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO it's better to group the test case in orders like what's in tidb:
- values of same type
- values of different types
const PRECEDENCE_ARRAY: i32 = -8; | ||
const PRECEDENCE_OBJECT: i32 = -9; | ||
const PRECEDENCE_STRING: i32 = -10; | ||
const PRECEDENCE_NUMBER: i32 = -11; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO it's better to define
PRECEDENCE_INTEGER = -11
PRECEDENCE_DOUBLE = -11
to map the real types, it's easier to understand since they are listed in real types in MySQL docs and in tidb's code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would caused the following warning:
this `match` has identical arm bodies
--> src/util/codec/mysql/json.rs:118:32
|
118 | Json::Double(_) => PRECEDENCE_DOUBLE,
| ^^^^^^^^^^^^^^^^^
|
= note: #[warn(match_same_arms)] on by default
note: same as this
--> src/util/codec/mysql/json.rs:117:29
|
117 | Json::I64(_) => PRECEDENCE_INTEGER,
| ^^^^^^^^^^^^^^^^^
note: consider refactoring into `Json::I64(_) | Json::Double(_)`
Rest LGTM |
src/util/codec/mysql/json.rs
Outdated
let precedence_diff = self.get_precedence() - right.get_precedence(); | ||
if precedence_diff == 0 { | ||
return match self.get_type_code() { | ||
TYPE_CODE_LITERAL => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could take the shortcut to skip running the comparison between Json::None
s.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
address comment @hhkbp2
LGTM |
("1.5", "2"), | ||
("1.5", "false"), | ||
("true", "1.5"), | ||
("true", "2"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not compatible with MySQL 5.7, although we don't have better implement. But we should comment it here.
LGTM. |
Hi,
This PR init comparison for type
json
. It's based on (#1874) ,we could start to review once PR-1874 has been merged:Meanwhile, the related PR in
tidb
is (pingcap/tidb#3307) and related source file is compare.go@BusyJay @hicqu @andelf PTAL