Skip to content
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

Merged
merged 49 commits into from Jun 15, 2017
Merged

mysql/json: support comparison #1893

merged 49 commits into from Jun 15, 2017

Conversation

AndreMouche
Copy link
Member

@AndreMouche AndreMouche commented Jun 6, 2017

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

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)
Copy link
Contributor

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?

@AndreMouche AndreMouche changed the title [Pending] mysql/json: support comparison [WIP] mysql/json: support comparison Jun 6, 2017
@@ -12,6 +12,7 @@
// limitations under the License.

use super::Result;
use std::cmp::{Ordering, Ord, PartialEq, PartialOrd};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ord, PartialEq, PartialOrd

@@ -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)]
Copy link
Contributor

@andelf andelf Jun 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#![allow(dead_code)]

#[allow(dead_code)]
const PRECEDENCE_DATE: i32 = -6;
const PRECEDENCE_BOOLEAN: i32 = -7;
const PRECEDENCE_ARRAY: i32 = -8;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why negative

Copy link
Member Author

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


// Json implement type json used in tikv, it specifies the following
// Json implements type json used in tikv, it specifies the following
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

///

return match self.get_type_code() {
TYPE_CODE_LITERAL => {
let left_data = self.as_literal().unwrap();
let right_data = right.as_literal().unwrap();
Copy link
Contributor

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

Copy link
Contributor

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. 😆

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

address comment @andelf


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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

treats

}
}

impl Eq for Json {}
Copy link
Contributor

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?

(&json_bool_false, &json_bool_true),
];

for (left, right) in test_cases {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for (&left, &right) in

Copy link
Member Author

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

@andelf

@@ -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];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space ?

@andelf
Copy link
Contributor

andelf commented Jun 14, 2017

LGTM

@AndreMouche
Copy link
Member Author

@hicqu @hhkbp2 @lishihai9017 PTAL,THX

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![
Copy link
Contributor

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:

  1. values of same type
  2. values of different types

const PRECEDENCE_ARRAY: i32 = -8;
const PRECEDENCE_OBJECT: i32 = -9;
const PRECEDENCE_STRING: i32 = -10;
const PRECEDENCE_NUMBER: i32 = -11;
Copy link
Contributor

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.

Copy link
Member Author

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(_)`

@hhkbp2

@hhkbp2
Copy link
Contributor

hhkbp2 commented Jun 15, 2017

Rest LGTM

let precedence_diff = self.get_precedence() - right.get_precedence();
if precedence_diff == 0 {
return match self.get_type_code() {
TYPE_CODE_LITERAL => {
Copy link
Contributor

@hhkbp2 hhkbp2 Jun 15, 2017

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::Nones.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

address comment @hhkbp2

@hhkbp2
Copy link
Contributor

hhkbp2 commented Jun 15, 2017

LGTM

@hhkbp2 hhkbp2 merged commit f463c32 into master Jun 15, 2017
@hhkbp2 hhkbp2 deleted the shirly/json_cmp branch June 15, 2017 08:42
("1.5", "2"),
("1.5", "false"),
("true", "1.5"),
("true", "2"),
Copy link
Contributor

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.

@hicqu
Copy link
Contributor

hicqu commented Jun 15, 2017

LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants