mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-24 00:40:40 +00:00
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:
@@ -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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user