diff --git a/src/execution/volcano/dql/describe.rs b/src/execution/volcano/dql/describe.rs index dd0d32a0..c24c60b2 100644 --- a/src/execution/volcano/dql/describe.rs +++ b/src/execution/volcano/dql/describe.rs @@ -59,7 +59,7 @@ impl Describe { datatype .raw_len() .map(|len| len.to_string()) - .unwrap_or_default(), + .unwrap_or_else(|| "DYNAMIC".to_string()), ))), Arc::new(DataValue::Utf8(Some(column.nullable.to_string()))), key_fn(column), diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 95a1a06e..70a4d76a 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -115,10 +115,15 @@ impl Tuple { } else { let mut value_bytes = value.to_raw(); - if types[i].raw_len().is_none() { + if let Some(len) = types[i].raw_len() { + let difference = len.saturating_sub(value_bytes.len()); + + bytes.append(&mut value_bytes); + bytes.append(&mut vec![0; difference]); + } else { bytes.append(&mut (value_bytes.len() as u32).encode_fixed_vec()); + bytes.append(&mut value_bytes); } - bytes.append(&mut value_bytes); } } diff --git a/src/types/value.rs b/src/types/value.rs index e94acee6..ca7334eb 100644 --- a/src/types/value.rs +++ b/src/types/value.rs @@ -440,7 +440,18 @@ impl DataValue { buf.copy_from_slice(bytes); f64::from_ne_bytes(buf) })), - LogicalType::Char(_) | LogicalType::Varchar(_) => DataValue::Utf8( + LogicalType::Char(_) => { + // https://dev.mysql.com/doc/refman/8.0/en/char.html#:~:text=If%20a%20given%20value%20is%20stored%20into%20the%20CHAR(4)%20and%20VARCHAR(4)%20columns%2C%20the%20values%20retrieved%20from%20the%20columns%20are%20not%20always%20the%20same%20because%20trailing%20spaces%20are%20removed%20from%20CHAR%20columns%20upon%20retrieval.%20The%20following%20example%20illustrates%20this%20difference%3A + let value = (!bytes.is_empty()).then(|| { + let last_non_zero_index = match bytes.iter().rposition(|&x| x != 0) { + Some(index) => index + 1, + None => 0, + }; + String::from_utf8(bytes[0..last_non_zero_index].to_owned()).unwrap() + }); + DataValue::Utf8(value) + } + LogicalType::Varchar(_) => DataValue::Utf8( (!bytes.is_empty()).then(|| String::from_utf8(bytes.to_owned()).unwrap()), ), LogicalType::Date => { diff --git a/tests/slt/describe.slt b/tests/slt/describe.slt index 9541eaa4..c5137ff3 100644 --- a/tests/slt/describe.slt +++ b/tests/slt/describe.slt @@ -4,9 +4,9 @@ create table t9 (c1 int primary key, c2 int default 0, c3 varchar unique); query TTTTI describe t9; ---- -c1 INTEGER false PRIMARY null -c2 INTEGER true EMPTY 0 -c3 VARCHAR true UNIQUE null +c1 INTEGER 4 false PRIMARY null +c2 INTEGER 4 true EMPTY 0 +c3 VARCHAR DYNAMIC true UNIQUE null statement ok drop table t9; \ No newline at end of file diff --git a/tests/slt/insert.slt b/tests/slt/insert.slt index 6a1d529c..b38e252e 100644 --- a/tests/slt/insert.slt +++ b/tests/slt/insert.slt @@ -44,6 +44,9 @@ select * from t 7 10 1 null 8 null null null +statement ok +drop table t; + statement ok create table t1(id int primary key, v1 bigint default 233) @@ -73,4 +76,28 @@ select * from t1 2 233 3 233 4 0 -5 233 \ No newline at end of file +5 233 + +statement ok +drop table t1; + +statement ok +create table t2(id int primary key, v1 char(10), v2 varchar); + +statement ok +insert into t2 (id, v1, v2) values (0, 'foo', 'foo'); + +query ITT +select * from t2; +---- +0 foo foo + +query B +select v1 = v2 from t2; +---- +true + +statement ok +drop table t2; + + diff --git a/tests/slt/sql_2016/E021_10.slt b/tests/slt/sql_2016/E021_10.slt index 7eb06679..a22291ca 100644 --- a/tests/slt/sql_2016/E021_10.slt +++ b/tests/slt/sql_2016/E021_10.slt @@ -1,12 +1,12 @@ # E021-10: Implicit casting among the fixed-length and variable-length character string types -# TODO: CHARACTER and CHARACTER VARYING +statement ok +CREATE TABLE TABLE_E021_10_01_01 ( ID INT PRIMARY KEY, A CHARACTER ( 10 ) , B CHARACTER VARYING ( 15 ) ); -# statement ok -# CREATE TABLE TABLE_E021_10_01_01 ( A CHARACTER ( 10 ) , B CHARACTER VARYING ( 15 ) ); +statement ok +INSERT INTO TABLE_E021_10_01_01 ( ID, A, B ) VALUES ( 0, 'foo' , 'bar' ); -# statement ok -# INSERT INTO TABLE_E021_10_01_01 ( A, B ) VALUES ( 'foo' , 'bar' ); - -# query B -# SELECT A = B FROM TABLE_E021_10_01_01 +query B +SELECT A = B FROM TABLE_E021_10_01_01 +---- +false