From e95b21f4fc293a576b4e6c7b768b46ee3f8a028f Mon Sep 17 00:00:00 2001 From: Jiacai Liu Date: Fri, 2 Dec 2022 14:09:54 +0800 Subject: [PATCH] feat: convert table name to lowercase when not quoted (#444) * normalize table name * add testcase --- sql/src/ast.rs | 12 +++- .../local/03_dml/case_insensitive.result | 69 +++++++++++++++++++ tests/cases/local/03_dml/case_insensitive.sql | 34 +++++++++ 3 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 tests/cases/local/03_dml/case_insensitive.result create mode 100644 tests/cases/local/03_dml/case_insensitive.sql diff --git a/sql/src/ast.rs b/sql/src/ast.rs index 729fc8ff43..d2a6fe1264 100644 --- a/sql/src/ast.rs +++ b/sql/src/ast.rs @@ -3,7 +3,7 @@ //! SQL statement use sqlparser::ast::{ - ColumnDef, ObjectName, SqlOption, Statement as SqlStatement, TableConstraint, + ColumnDef, Ident, ObjectName, SqlOption, Statement as SqlStatement, TableConstraint, }; /// Statement representations @@ -33,6 +33,14 @@ impl TableName { pub fn is_empty(&self) -> bool { self.0 .0.is_empty() } + + // Normalize an identifer to a lowercase string unless the identifier is quoted. + fn normalize_ident(id: &Ident) -> String { + match id.quote_style { + Some(_) => id.value.clone(), + None => id.value.to_ascii_lowercase(), + } + } } impl ToString for TableName { @@ -40,7 +48,7 @@ impl ToString for TableName { self.0 .0 .iter() - .map(|ident| ident.value.as_str()) + .map(Self::normalize_ident) .collect::>() .join(".") } diff --git a/tests/cases/local/03_dml/case_insensitive.result b/tests/cases/local/03_dml/case_insensitive.result new file mode 100644 index 0000000000..a72e7afd81 --- /dev/null +++ b/tests/cases/local/03_dml/case_insensitive.result @@ -0,0 +1,69 @@ +DROP TABLE IF EXISTS case_insensitive_table1; + +affected_rows: 0 + +CREATE TABLE case_insensitive_table1 ( + ts timestamp NOT NULL, + value1 double, + timestamp KEY (ts)) ENGINE=Analytic +WITH( + enable_ttl='false' +); + +affected_rows: 0 + +INSERT INTO case_insensitive_table1 (ts, value1) + VALUES (1, 10), (2, 20), (3, 30); + +affected_rows: 3 + +SELECT + * +FROM + case_insensitive_table1; + +ts,tsid,value1, +Timestamp(Timestamp(1)),Int64(0),Double(10.0), +Timestamp(Timestamp(2)),Int64(0),Double(20.0), +Timestamp(Timestamp(3)),Int64(0),Double(30.0), + + +SELECT + * +FROM + CASE_INSENSITIVE_TABLE1; + +ts,tsid,value1, +Timestamp(Timestamp(1)),Int64(0),Double(10.0), +Timestamp(Timestamp(2)),Int64(0),Double(20.0), +Timestamp(Timestamp(3)),Int64(0),Double(30.0), + + +SHOW CREATE TABLE case_insensitive_table1; + +Table,Create Table, +String(StringBytes(b"case_insensitive_table1")),String(StringBytes(b"CREATE TABLE `case_insensitive_table1` (`ts` timestamp NOT NULL, `tsid` uint64 NOT NULL, `value1` double, PRIMARY KEY(ts,tsid), TIMESTAMP KEY(ts)) ENGINE=Analytic WITH(arena_block_size='2097152', compaction_strategy='default', compression='ZSTD', enable_ttl='false', num_rows_per_row_group='8192', segment_duration='', storage_format='COLUMNAR', ttl='7d', update_mode='OVERWRITE', write_buffer_size='33554432')")), + + +SHOW CREATE TABLE CASE_INSENSITIVE_TABLE1; + +Table,Create Table, +String(StringBytes(b"case_insensitive_table1")),String(StringBytes(b"CREATE TABLE `case_insensitive_table1` (`ts` timestamp NOT NULL, `tsid` uint64 NOT NULL, `value1` double, PRIMARY KEY(ts,tsid), TIMESTAMP KEY(ts)) ENGINE=Analytic WITH(arena_block_size='2097152', compaction_strategy='default', compression='ZSTD', enable_ttl='false', num_rows_per_row_group='8192', segment_duration='', storage_format='COLUMNAR', ttl='7d', update_mode='OVERWRITE', write_buffer_size='33554432')")), + + +DESC case_insensitive_table1; + +name,type,is_primary,is_nullable,is_tag, +String(StringBytes(b"ts")),String(StringBytes(b"timestamp")),Boolean(true),Boolean(false),Boolean(false), +String(StringBytes(b"tsid")),String(StringBytes(b"uint64")),Boolean(true),Boolean(false),Boolean(false), +String(StringBytes(b"value1")),String(StringBytes(b"double")),Boolean(false),Boolean(true),Boolean(false), + + +DESC CASE_INSENSITIVE_TABLE1; + +name,type,is_primary,is_nullable,is_tag, +String(StringBytes(b"ts")),String(StringBytes(b"timestamp")),Boolean(true),Boolean(false),Boolean(false), +String(StringBytes(b"tsid")),String(StringBytes(b"uint64")),Boolean(true),Boolean(false),Boolean(false), +String(StringBytes(b"value1")),String(StringBytes(b"double")),Boolean(false),Boolean(true),Boolean(false), + + diff --git a/tests/cases/local/03_dml/case_insensitive.sql b/tests/cases/local/03_dml/case_insensitive.sql new file mode 100644 index 0000000000..bb39a443d8 --- /dev/null +++ b/tests/cases/local/03_dml/case_insensitive.sql @@ -0,0 +1,34 @@ + +DROP TABLE IF EXISTS case_insensitive_table1; + + +CREATE TABLE case_insensitive_table1 ( + ts timestamp NOT NULL, + value1 double, + timestamp KEY (ts)) ENGINE=Analytic +WITH( + enable_ttl='false' +); + +INSERT INTO case_insensitive_table1 (ts, value1) + VALUES (1, 10), (2, 20), (3, 30); + + +SELECT + * +FROM + case_insensitive_table1; + +SELECT + * +FROM + CASE_INSENSITIVE_TABLE1; + + +SHOW CREATE TABLE case_insensitive_table1; + +SHOW CREATE TABLE CASE_INSENSITIVE_TABLE1; + +DESC case_insensitive_table1; + +DESC CASE_INSENSITIVE_TABLE1;