feat: integration test (#770)

* feat: add insert test cases

* fix: update results after rebase develop

* feat: supports unsigned integer types and big_insert test

* test: add insert_invalid test

* feat: supports time index constraint for bigint type

* chore: time index column at last

* test: adds more order, limit test

* fix: style

* feat: adds numbers table in standable memory catalog mode

* feat: enable fail_fast and test_filter in sqlness

* feat: add more tests

* fix: test_filter

* test: add alter tests

* feat: supports if_not_exists when create database

* test: filter_push_down and catalog test

* fix: compile error

* fix: delete output file

* chore: ignore integration test output in git

* test: update all integration test results

* fix: by code review

* chore: revert .gitignore

* feat: sort the show tables/databases results

* chore: remove issue link

* fix: compile error and code format after rebase

* test: update all integration test results
This commit is contained in:
dennis zhuang
2023-01-10 18:15:50 +08:00
committed by GitHub
parent 32d51947a4
commit 9428e70971
63 changed files with 2788 additions and 76 deletions

View File

@@ -46,7 +46,7 @@ impl<'a> ParserContext<'a> {
Token::Word(w) => match w.keyword {
Keyword::TABLE => self.parse_create_table(),
Keyword::DATABASE => self.parse_create_database(),
Keyword::SCHEMA | Keyword::DATABASE => self.parse_create_database(),
_ => self.unsupported(w.to_string()),
},
@@ -57,6 +57,10 @@ impl<'a> ParserContext<'a> {
fn parse_create_database(&mut self) -> Result<Statement> {
self.parser.next_token();
let if_not_exists =
self.parser
.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
let database_name = self
.parser
.parse_object_name()
@@ -68,6 +72,7 @@ impl<'a> ParserContext<'a> {
Ok(Statement::CreateDatabase(CreateDatabase {
name: database_name,
if_not_exists,
}))
}
@@ -253,8 +258,10 @@ impl<'a> ParserContext<'a> {
.parse_column_def()
.context(SyntaxSnafu { sql: self.sql })?;
if !matches!(column.data_type, DataType::Timestamp(_, _))
|| matches!(self.parser.peek_token(), Token::Comma)
if !matches!(
column.data_type,
DataType::Timestamp(_, _) | DataType::BigInt(_)
) || matches!(self.parser.peek_token(), Token::Comma)
{
columns.push(column);
return Ok(());
@@ -290,6 +297,7 @@ impl<'a> ParserContext<'a> {
is_primary: false,
};
// TIME INDEX option means NOT NULL implicitly.
column.options = vec![ColumnOptionDef {
name: None,
option: NotNull,
@@ -297,7 +305,7 @@ impl<'a> ParserContext<'a> {
columns.push(column);
constraints.push(constraint);
if let Token::Comma = self.parser.peek_token() {
if matches!(self.parser.peek_token(), Token::Comma | Token::RParen) {
return Ok(());
}
@@ -580,6 +588,19 @@ mod tests {
match &stmts[0] {
Statement::CreateDatabase(c) => {
assert_eq!(c.name.to_string(), "prometheus");
assert!(!c.if_not_exists);
}
_ => unreachable!(),
}
let sql = "create database if not exists prometheus";
let stmts = ParserContext::create_with_dialect(sql, &GenericDialect {}).unwrap();
assert_eq!(1, stmts.len());
match &stmts[0] {
Statement::CreateDatabase(c) => {
assert_eq!(c.name.to_string(), "prometheus");
assert!(c.if_not_exists);
}
_ => unreachable!(),
}
@@ -838,6 +859,39 @@ ENGINE=mito";
let result3 = ParserContext::create_with_dialect(sql3, &GenericDialect {}).unwrap();
assert_ne!(result1, result3);
// BIGINT as time index
let sql1 = r"
CREATE TABLE monitor (
host_id INT,
idc STRING,
b bigint TIME INDEX,
cpu DOUBLE DEFAULT 0,
memory DOUBLE,
PRIMARY KEY (host),
)
ENGINE=mito";
let result1 = ParserContext::create_with_dialect(sql1, &GenericDialect {}).unwrap();
if let Statement::CreateTable(c) = &result1[0] {
assert_eq!(c.constraints.len(), 2);
let tc = c.constraints[0].clone();
match tc {
TableConstraint::Unique {
name,
columns,
is_primary,
} => {
assert_eq!(name.unwrap().to_string(), "__time_index");
assert_eq!(columns.len(), 1);
assert_eq!(&columns[0].value, "b");
assert!(!is_primary);
}
_ => panic!("should be time index constraint"),
};
} else {
panic!("should be create_table statement");
}
}
#[test]

View File

@@ -311,8 +311,15 @@ pub fn sql_column_def_to_grpc_column_def(col: ColumnDef) -> Result<api::v1::Colu
pub fn sql_data_type_to_concrete_data_type(data_type: &SqlDataType) -> Result<ConcreteDataType> {
match data_type {
SqlDataType::BigInt(_) => Ok(ConcreteDataType::int64_datatype()),
SqlDataType::Int(_) => Ok(ConcreteDataType::int32_datatype()),
SqlDataType::UnsignedBigInt(_) => Ok(ConcreteDataType::uint64_datatype()),
SqlDataType::Int(_) | SqlDataType::Integer(_) => Ok(ConcreteDataType::int32_datatype()),
SqlDataType::UnsignedInt(_) | SqlDataType::UnsignedInteger(_) => {
Ok(ConcreteDataType::uint32_datatype())
}
SqlDataType::SmallInt(_) => Ok(ConcreteDataType::int16_datatype()),
SqlDataType::UnsignedSmallInt(_) => Ok(ConcreteDataType::uint16_datatype()),
SqlDataType::TinyInt(_) => Ok(ConcreteDataType::int8_datatype()),
SqlDataType::UnsignedTinyInt(_) => Ok(ConcreteDataType::uint8_datatype()),
SqlDataType::Char(_)
| SqlDataType::Varchar(_)
| SqlDataType::Text
@@ -376,6 +383,10 @@ mod tests {
ConcreteDataType::int64_datatype(),
);
check_type(SqlDataType::Int(None), ConcreteDataType::int32_datatype());
check_type(
SqlDataType::Integer(None),
ConcreteDataType::int32_datatype(),
);
check_type(
SqlDataType::SmallInt(None),
ConcreteDataType::int16_datatype(),
@@ -406,6 +417,22 @@ mod tests {
SqlDataType::Varbinary(None),
ConcreteDataType::binary_datatype(),
);
check_type(
SqlDataType::UnsignedBigInt(None),
ConcreteDataType::uint64_datatype(),
);
check_type(
SqlDataType::UnsignedInt(None),
ConcreteDataType::uint32_datatype(),
);
check_type(
SqlDataType::UnsignedSmallInt(None),
ConcreteDataType::uint16_datatype(),
);
check_type(
SqlDataType::UnsignedTinyInt(None),
ConcreteDataType::uint8_datatype(),
);
}
#[test]

View File

@@ -47,4 +47,6 @@ pub struct PartitionEntry {
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct CreateDatabase {
pub name: ObjectName,
/// Create if not exists
pub if_not_exists: bool,
}