chore: update datafusion family (#5814)

This commit is contained in:
LFC
2025-04-09 10:20:55 +08:00
committed by GitHub
parent 7e3cad8a55
commit 311727939d
83 changed files with 902 additions and 1027 deletions

View File

@@ -17,7 +17,7 @@ use sqlparser::ast::{Ident, Query};
use sqlparser::dialect::Dialect;
use sqlparser::keywords::Keyword;
use sqlparser::parser::{Parser, ParserError, ParserOptions};
use sqlparser::tokenizer::{Token, TokenWithLocation};
use sqlparser::tokenizer::{Token, TokenWithSpan};
use crate::ast::{Expr, ObjectName};
use crate::error::{self, Result, SyntaxSnafu};
@@ -112,7 +112,7 @@ impl ParserContext<'_> {
.try_with_sql(sql)
.context(SyntaxSnafu)?;
let function_name = parser.parse_identifier(false).context(SyntaxSnafu)?;
let function_name = parser.parse_identifier().context(SyntaxSnafu)?;
parser
.parse_function(ObjectName(vec![function_name]))
.context(SyntaxSnafu)
@@ -178,12 +178,12 @@ impl ParserContext<'_> {
Keyword::USE => {
let _ = self.parser.next_token();
let database_name = self.parser.parse_identifier(false).context(
let database_name = self.parser.parse_identifier().with_context(|_| {
error::UnexpectedSnafu {
expected: "a database name",
actual: self.peek_token_as_string(),
},
)?;
}
})?;
Ok(Statement::Use(
Self::canonicalize_identifier(database_name).value,
))
@@ -222,7 +222,7 @@ impl ParserContext<'_> {
}
// Report unexpected token
pub(crate) fn expected<T>(&self, expected: &str, found: TokenWithLocation) -> Result<T> {
pub(crate) fn expected<T>(&self, expected: &str, found: TokenWithSpan) -> Result<T> {
Err(ParserError::ParserError(format!(
"Expected {expected}, found: {found}",
)))
@@ -255,10 +255,7 @@ impl ParserContext<'_> {
if ident.quote_style.is_some() {
ident
} else {
Ident {
value: ident.value.to_lowercase(),
quote_style: None,
}
Ident::new(ident.value.to_lowercase())
}
}
@@ -280,14 +277,6 @@ impl ParserContext<'_> {
pub(crate) fn parse_object_name(&mut self) -> std::result::Result<ObjectName, ParserError> {
self.parser.parse_object_name(false)
}
/// Simply a shortcut for sqlparser's same name method `parse_identifier`,
/// but with constant argument "false".
/// Because the argument is always "false" for us (it's introduced by BigQuery),
/// we don't want to write it again and again.
pub(crate) fn parse_identifier(parser: &mut Parser) -> std::result::Result<Ident, ParserError> {
parser.parse_identifier(false)
}
}
#[cfg(test)]

View File

@@ -20,7 +20,7 @@ use snafu::{ensure, ResultExt};
use sqlparser::ast::Ident;
use sqlparser::keywords::Keyword;
use sqlparser::parser::{Parser, ParserError};
use sqlparser::tokenizer::{Token, TokenWithLocation};
use sqlparser::tokenizer::{Token, TokenWithSpan};
use crate::error::{self, InvalidColumnOptionSnafu, Result, SetFulltextOptionSnafu};
use crate::parser::ParserContext;
@@ -124,8 +124,7 @@ impl ParserContext<'_> {
.expect_keyword(Keyword::COLUMN)
.context(error::SyntaxSnafu)?;
let name = Self::canonicalize_identifier(
Self::parse_identifier(&mut self.parser)
.context(error::SyntaxSnafu)?,
self.parser.parse_identifier().context(error::SyntaxSnafu)?,
);
AlterTableOperation::DropColumn { name }
}
@@ -205,9 +204,7 @@ impl ParserContext<'_> {
.expect_keyword(Keyword::COLUMN)
.context(error::SyntaxSnafu)?;
let column_name = Self::canonicalize_identifier(
self.parser
.parse_identifier(false)
.context(error::SyntaxSnafu)?,
self.parser.parse_identifier().context(error::SyntaxSnafu)?,
);
match self.parser.peek_token().token {
@@ -240,7 +237,7 @@ impl ParserContext<'_> {
column_name: Ident,
) -> Result<AlterTableOperation> {
match self.parser.next_token() {
TokenWithLocation {
TokenWithSpan {
token: Token::Word(w),
..
} if w.keyword == Keyword::FULLTEXT => {
@@ -252,7 +249,7 @@ impl ParserContext<'_> {
})
}
TokenWithLocation {
TokenWithSpan {
token: Token::Word(w),
..
} if w.value.eq_ignore_ascii_case(INVERTED) => {
@@ -264,7 +261,7 @@ impl ParserContext<'_> {
})
}
TokenWithLocation {
TokenWithSpan {
token: Token::Word(w),
..
} if w.value.eq_ignore_ascii_case("SKIPPING") => {
@@ -288,7 +285,7 @@ impl ParserContext<'_> {
fn parse_alter_column_set_index(&mut self, column_name: Ident) -> Result<AlterTableOperation> {
match self.parser.next_token() {
TokenWithLocation {
TokenWithSpan {
token: Token::Word(w),
..
} if w.keyword == Keyword::FULLTEXT => {
@@ -298,7 +295,7 @@ impl ParserContext<'_> {
self.parse_alter_column_fulltext(column_name)
}
TokenWithLocation {
TokenWithSpan {
token: Token::Word(w),
..
} if w.value.eq_ignore_ascii_case(INVERTED) => {
@@ -310,7 +307,7 @@ impl ParserContext<'_> {
})
}
TokenWithLocation {
TokenWithSpan {
token: Token::Word(w),
..
} if w.value.eq_ignore_ascii_case("SKIPPING") => {
@@ -416,8 +413,7 @@ fn parse_add_columns(parser: &mut Parser) -> std::result::Result<AddColumn, Pars
} else if let Token::Word(word) = parser.peek_token().token {
if word.value.eq_ignore_ascii_case("AFTER") {
let _ = parser.next_token();
let name =
ParserContext::canonicalize_identifier(ParserContext::parse_identifier(parser)?);
let name = ParserContext::canonicalize_identifier(parser.parse_identifier()?);
Some(AddColumnLocation::After {
column_name: name.value,
})
@@ -810,7 +806,7 @@ mod tests {
target_type,
} => {
assert_eq!("a", column_name.value);
assert_eq!(DataType::Text, *target_type);
assert_eq!(DataType::MediumText, *target_type);
}
_ => unreachable!(),
}
@@ -1012,10 +1008,7 @@ mod tests {
alter_operation,
&AlterTableOperation::UnsetIndex {
options: UnsetIndexOperation::Fulltext {
column_name: Ident {
value: "a".to_string(),
quote_style: None
}
column_name: Ident::new("a"),
}
}
);
@@ -1079,10 +1072,7 @@ mod tests {
alter_operation,
&AlterTableOperation::UnsetIndex {
options: UnsetIndexOperation::Inverted {
column_name: Ident {
value: "a".to_string(),
quote_style: None
}
column_name: Ident::new("a"),
}
}
);

View File

@@ -25,7 +25,7 @@ use sqlparser::dialect::keywords::Keyword;
use sqlparser::keywords::ALL_KEYWORDS;
use sqlparser::parser::IsOptional::Mandatory;
use sqlparser::parser::{Parser, ParserError};
use sqlparser::tokenizer::{Token, TokenWithLocation, Word};
use sqlparser::tokenizer::{Token, TokenWithSpan, Word};
use table::requests::validate_table_option;
use crate::ast::{ColumnDef, Ident};
@@ -299,7 +299,7 @@ impl<'a> ParserContext<'a> {
let comment = if self.parser.parse_keyword(Keyword::COMMENT) {
match self.parser.next_token() {
TokenWithLocation {
TokenWithSpan {
token: Token::SingleQuotedString(value, ..),
..
} => Some(value),
@@ -496,10 +496,7 @@ impl<'a> ParserContext<'a> {
time_index_opt_idx = Some(index);
let constraint = TableConstraint::TimeIndex {
column: Ident {
value: column.name().value.clone(),
quote_style: None,
},
column: Ident::new(column.name().value.clone()),
};
constraints.push(constraint);
}
@@ -547,7 +544,7 @@ impl<'a> ParserContext<'a> {
/// Parse the column name and check if it's valid.
fn parse_column_name(&mut self) -> std::result::Result<Ident, ParserError> {
let name = self.parser.parse_identifier(false)?;
let name = self.parser.parse_identifier()?;
if name.quote_style.is_none() &&
// "ALL_KEYWORDS" are sorted.
ALL_KEYWORDS.binary_search(&name.value.to_uppercase().as_str()).is_ok()
@@ -587,7 +584,7 @@ impl<'a> ParserContext<'a> {
let mut extensions = ColumnExtensions::default();
loop {
if parser.parse_keyword(Keyword::CONSTRAINT) {
let name = Some(parser.parse_identifier(false).context(SyntaxSnafu)?);
let name = Some(parser.parse_identifier().context(SyntaxSnafu)?);
if let Some(option) = Self::parse_optional_column_option(parser)? {
options.push(ColumnOptionDef { name, option });
} else {
@@ -625,7 +622,7 @@ impl<'a> ParserContext<'a> {
Ok(Some(ColumnOption::NotNull))
} else if parser.parse_keywords(&[Keyword::COMMENT]) {
match parser.next_token() {
TokenWithLocation {
TokenWithSpan {
token: Token::SingleQuotedString(value, ..),
..
} => Ok(Some(ColumnOption::Comment(value))),
@@ -844,7 +841,7 @@ impl<'a> ParserContext<'a> {
fn parse_optional_table_constraint(&mut self) -> Result<Option<TableConstraint>> {
match self.parser.next_token() {
TokenWithLocation {
TokenWithSpan {
token: Token::Word(w),
..
} if w.keyword == Keyword::PRIMARY => {
@@ -864,7 +861,7 @@ impl<'a> ParserContext<'a> {
.collect();
Ok(Some(TableConstraint::PrimaryKey { columns }))
}
TokenWithLocation {
TokenWithSpan {
token: Token::Word(w),
..
} if w.keyword == Keyword::TIME => {
@@ -1313,20 +1310,8 @@ SELECT max(c1), min(c2) FROM schema_2.table_2;";
};
let expected = CreateFlow {
flow_name: ObjectName(vec![Ident {
value: "task_1".to_string(),
quote_style: None,
}]),
sink_table_name: ObjectName(vec![
Ident {
value: "schema_1".to_string(),
quote_style: None,
},
Ident {
value: "table_1".to_string(),
quote_style: None,
},
]),
flow_name: ObjectName(vec![Ident::new("task_1")]),
sink_table_name: ObjectName(vec![Ident::new("schema_1"), Ident::new("table_1")]),
or_replace: true,
if_not_exists: true,
expire_after: Some(300),
@@ -1825,7 +1810,7 @@ ENGINE=mito";
ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
assert_eq!(
result.unwrap_err().output_msg(),
"Invalid SQL, error: Partition rule expr Identifier(Ident { value: \"b\", quote_style: None }) is not a binary expr"
r#"Invalid SQL, error: Partition rule expr Identifier(Ident { value: "b", quote_style: None, span: Span(Location(4,5)..Location(4,6)) }) is not a binary expr"#
);
}

View File

@@ -24,7 +24,7 @@ impl ParserContext<'_> {
self.parser
.expect_keyword(Keyword::DEALLOCATE)
.context(SyntaxSnafu)?;
let stmt_name = self.parser.parse_identifier(false).context(SyntaxSnafu)?;
let stmt_name = self.parser.parse_identifier().context(SyntaxSnafu)?;
Ok(stmt_name.value)
}
}

View File

@@ -27,7 +27,7 @@ impl ParserContext<'_> {
self.parser
.expect_keyword(Keyword::EXECUTE)
.context(SyntaxSnafu)?;
let stmt_name = self.parser.parse_identifier(false).context(SyntaxSnafu)?;
let stmt_name = self.parser.parse_identifier().context(SyntaxSnafu)?;
if self.parser.parse_keyword(Keyword::USING) {
let param_list = self
.parser

View File

@@ -37,6 +37,7 @@ impl ParserContext<'_> {
#[cfg(test)]
mod tests {
use sqlparser::ast::helpers::attached_token::AttachedToken;
use sqlparser::ast::{
GroupByExpr, Query as SpQuery, Statement as SpStatement, WildcardAdditionalOptions,
};
@@ -69,6 +70,8 @@ mod tests {
partitions: vec![],
version: None,
with_ordinality: false,
json_path: None,
sample: None,
},
joins: vec![],
}],
@@ -86,6 +89,7 @@ mod tests {
prewhere: None,
window_before_qualify: false,
connect_by: None,
select_token: AttachedToken::empty(),
};
let sp_statement = SpStatement::Query(Box::new(SpQuery {
@@ -110,6 +114,7 @@ mod tests {
format: None,
query_plan: false,
options: None,
estimate: false,
})
.unwrap();

View File

@@ -26,7 +26,7 @@ impl ParserContext<'_> {
self.parser
.expect_keyword(Keyword::PREPARE)
.context(SyntaxSnafu)?;
let stmt_name = self.parser.parse_identifier(false).context(SyntaxSnafu)?;
let stmt_name = self.parser.parse_identifier().context(SyntaxSnafu)?;
self.parser
.expect_keyword(Keyword::FROM)
.context(SyntaxSnafu)?;

View File

@@ -38,10 +38,7 @@ impl ParserContext<'_> {
})),
SpStatement::SetTimeZone { value, .. } => Ok(Statement::SetVariables(SetVariables {
variable: ObjectName(vec![Ident {
value: "TIMEZONE".to_string(),
quote_style: None,
}]),
variable: ObjectName(vec![Ident::new("TIMEZONE")]),
value: vec![value],
})),

View File

@@ -295,7 +295,7 @@ impl ParserContext<'_> {
Keyword::LIKE => {
self.parser.next_token();
Ok(ShowKind::Like(
Self::parse_identifier(&mut self.parser).with_context(|_| {
self.parser.parse_identifier().with_context(|_| {
error::UnexpectedSnafu {
expected: "LIKE",
actual: self.peek_token_as_string(),
@@ -498,12 +498,12 @@ impl ParserContext<'_> {
))),
Token::Word(w) => match w.keyword {
Keyword::LIKE => Ok(Statement::ShowDatabases(ShowDatabases::new(
ShowKind::Like(Self::parse_identifier(&mut self.parser).with_context(
|_| error::UnexpectedSnafu {
ShowKind::Like(self.parser.parse_identifier().with_context(|_| {
error::UnexpectedSnafu {
expected: "LIKE",
actual: tok.to_string(),
},
)?),
}
})?),
full,
))),
Keyword::WHERE => Ok(Statement::ShowDatabases(ShowDatabases::new(
@@ -639,6 +639,7 @@ mod tests {
kind: ShowKind::Like(sqlparser::ast::Ident {
value: _,
quote_style: None,
span: _,
}),
..
})
@@ -698,6 +699,7 @@ mod tests {
kind: ShowKind::Like(sqlparser::ast::Ident {
value: _,
quote_style: None,
span: _,
}),
database: None,
full: false
@@ -716,6 +718,7 @@ mod tests {
kind: ShowKind::Like(sqlparser::ast::Ident {
value: _,
quote_style: None,
span: _,
}),
database: Some(_),
full: false
@@ -806,6 +809,7 @@ mod tests {
kind: ShowKind::Like(sqlparser::ast::Ident {
value: _,
quote_style: None,
span: _,
}),
database: None,
full: true
@@ -824,6 +828,7 @@ mod tests {
kind: ShowKind::Like(sqlparser::ast::Ident {
value: _,
quote_style: None,
span: _,
}),
database: Some(_),
full: true

View File

@@ -217,7 +217,7 @@ impl ParserContext<'_> {
while matches!(parser.peek_token().token, Token::Comma) {
let _skip_token = parser.next_token();
}
let index = parser.next_token().location.column as usize;
let index = parser.next_token().span.start.column as usize;
if index == 0 {
return Err(ParserError::ParserError("empty TQL query".to_string()));
}

View File

@@ -281,12 +281,7 @@ pub fn sql_value_to_value(
if let Some(unary_op) = unary_op {
match unary_op {
UnaryOperator::Plus | UnaryOperator::Minus | UnaryOperator::Not => {}
UnaryOperator::PGBitwiseNot
| UnaryOperator::PGSquareRoot
| UnaryOperator::PGCubeRoot
| UnaryOperator::PGPostfixFactorial
| UnaryOperator::PGPrefixFactorial
| UnaryOperator::PGAbs => {
_ => {
return UnsupportedUnaryOpSnafu { unary_op }.fail();
}
}
@@ -570,9 +565,12 @@ pub fn sql_data_type_to_concrete_data_type(data_type: &SqlDataType) -> Result<Co
SqlDataType::Char(_)
| SqlDataType::Varchar(_)
| SqlDataType::Text
| SqlDataType::TinyText
| SqlDataType::MediumText
| SqlDataType::LongText
| SqlDataType::String(_) => Ok(ConcreteDataType::string_datatype()),
SqlDataType::Float(_) => Ok(ConcreteDataType::float32_datatype()),
SqlDataType::Double | SqlDataType::Float64 => Ok(ConcreteDataType::float64_datatype()),
SqlDataType::Double(_) | SqlDataType::Float64 => Ok(ConcreteDataType::float64_datatype()),
SqlDataType::Boolean => Ok(ConcreteDataType::boolean_datatype()),
SqlDataType::Date => Ok(ConcreteDataType::date_datatype()),
SqlDataType::Binary(_)
@@ -636,7 +634,7 @@ pub fn concrete_data_type_to_sql_data_type(data_type: &ConcreteDataType) -> Resu
ConcreteDataType::UInt8(_) => Ok(SqlDataType::UnsignedTinyInt(None)),
ConcreteDataType::String(_) => Ok(SqlDataType::String(None)),
ConcreteDataType::Float32(_) => Ok(SqlDataType::Float(None)),
ConcreteDataType::Float64(_) => Ok(SqlDataType::Double),
ConcreteDataType::Float64(_) => Ok(SqlDataType::Double(ExactNumberInfo::None)),
ConcreteDataType::Boolean(_) => Ok(SqlDataType::Boolean),
ConcreteDataType::Date(_) => Ok(SqlDataType::Date),
ConcreteDataType::Timestamp(ts_type) => Ok(SqlDataType::Timestamp(
@@ -721,7 +719,10 @@ mod tests {
SqlDataType::Float(None),
ConcreteDataType::float32_datatype(),
);
check_type(SqlDataType::Double, ConcreteDataType::float64_datatype());
check_type(
SqlDataType::Double(ExactNumberInfo::None),
ConcreteDataType::float64_datatype(),
);
check_type(SqlDataType::Boolean, ConcreteDataType::boolean_datatype());
check_type(SqlDataType::Date, ConcreteDataType::date_datatype());
check_type(
@@ -1187,7 +1188,7 @@ mod tests {
// test basic
let column_def = ColumnDef {
name: "col".into(),
data_type: SqlDataType::Double,
data_type: SqlDataType::Double(ExactNumberInfo::None),
collation: None,
options: vec![],
};
@@ -1203,7 +1204,7 @@ mod tests {
// test not null
let column_def = ColumnDef {
name: "col".into(),
data_type: SqlDataType::Double,
data_type: SqlDataType::Double(ExactNumberInfo::None),
collation: None,
options: vec![ColumnOptionDef {
name: None,
@@ -1217,7 +1218,7 @@ mod tests {
// test primary key
let column_def = ColumnDef {
name: "col".into(),
data_type: SqlDataType::Double,
data_type: SqlDataType::Double(ExactNumberInfo::None),
collation: None,
options: vec![ColumnOptionDef {
name: None,
@@ -1290,7 +1291,7 @@ mod tests {
pub fn test_has_primary_key_option() {
let column_def = ColumnDef {
name: "col".into(),
data_type: SqlDataType::Double,
data_type: SqlDataType::Double(ExactNumberInfo::None),
collation: None,
options: vec![],
};
@@ -1298,7 +1299,7 @@ mod tests {
let column_def = ColumnDef {
name: "col".into(),
data_type: SqlDataType::Double,
data_type: SqlDataType::Double(ExactNumberInfo::None),
collation: None,
options: vec![ColumnOptionDef {
name: None,
@@ -1316,7 +1317,7 @@ mod tests {
let column_def = Column {
column_def: ColumnDef {
name: "col".into(),
data_type: SqlDataType::Double,
data_type: SqlDataType::Double(ExactNumberInfo::None),
collation: None,
options: vec![],
},

View File

@@ -14,13 +14,13 @@
use serde::Serialize;
use sqlparser::ast::{
Insert as SpInsert, ObjectName, Query, SetExpr, Statement, UnaryOperator, Values,
Insert as SpInsert, ObjectName, Query, SetExpr, Statement, TableObject, UnaryOperator, Values,
};
use sqlparser::parser::ParserError;
use sqlparser_derive::{Visit, VisitMut};
use crate::ast::{Expr, Value};
use crate::error::Result;
use crate::error::{Result, UnsupportedSnafu};
use crate::statements::query::Query as GtQuery;
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
@@ -39,9 +39,17 @@ macro_rules! parse_fail {
}
impl Insert {
pub fn table_name(&self) -> &ObjectName {
pub fn table_name(&self) -> Result<&ObjectName> {
match &self.inner {
Statement::Insert(insert) => &insert.table_name,
Statement::Insert(insert) => {
let TableObject::TableName(name) = &insert.table else {
return UnsupportedSnafu {
keyword: "TABLE FUNCTION".to_string(),
}
.fail();
};
Ok(name)
}
_ => unreachable!(),
}
}

View File

@@ -334,13 +334,7 @@ mod tests {
assert_eq!("", format!("{}", ShowKind::All));
assert_eq!(
"LIKE test",
format!(
"{}",
ShowKind::Like(Ident {
value: "test".to_string(),
quote_style: None,
})
)
format!("{}", ShowKind::Like(Ident::new("test")),)
);
assert_eq!(
"WHERE NOT a",
@@ -348,10 +342,7 @@ mod tests {
"{}",
ShowKind::Where(Expr::UnaryOp {
op: UnaryOperator::Not,
expr: Box::new(Expr::Identifier(Ident {
value: "a".to_string(),
quote_style: None,
})),
expr: Box::new(Expr::Identifier(Ident::new("a"))),
})
)
);

View File

@@ -16,8 +16,8 @@ use std::ops::ControlFlow;
use datatypes::data_type::DataType as GreptimeDataType;
use sqlparser::ast::{
DataType, Expr, Function, FunctionArg, FunctionArgExpr, FunctionArgumentList, Ident,
ObjectName, Value,
DataType, ExactNumberInfo, Expr, Function, FunctionArg, FunctionArgExpr, FunctionArgumentList,
Ident, ObjectName, Value,
};
use crate::error::Result;
@@ -91,6 +91,7 @@ impl TransformRule for TypeAliasTransformRule {
over: None,
parameters: sqlparser::ast::FunctionArguments::None,
within_group: vec![],
uses_odbc_syntax: false,
}
}
@@ -166,7 +167,7 @@ pub(crate) fn get_type_by_alias(data_type: &DataType) -> Option<DataType> {
DataType::UInt32 => Some(DataType::UnsignedInt(None)),
DataType::UInt64 => Some(DataType::UnsignedBigInt(None)),
DataType::Float32 => Some(DataType::Float(None)),
DataType::Float64 => Some(DataType::Double),
DataType::Float64 => Some(DataType::Double(ExactNumberInfo::None)),
DataType::Bool => Some(DataType::Boolean),
DataType::Datetime(_) => Some(DataType::Timestamp(Some(6), TimezoneInfo::None)),
_ => None,
@@ -207,7 +208,7 @@ pub(crate) fn get_data_type_by_alias_name(name: &str) -> Option<DataType> {
"UINT32" => Some(DataType::UnsignedInt(None)),
"UINT64" => Some(DataType::UnsignedBigInt(None)),
"FLOAT32" => Some(DataType::Float(None)),
"FLOAT64" => Some(DataType::Double),
"FLOAT64" => Some(DataType::Double(ExactNumberInfo::None)),
// String type alias
"TINYTEXT" | "MEDIUMTEXT" | "LONGTEXT" => Some(DataType::Text),
_ => None,
@@ -226,15 +227,15 @@ mod tests {
fn test_get_data_type_by_alias_name() {
assert_eq!(
get_data_type_by_alias_name("float64"),
Some(DataType::Double)
Some(DataType::Double(ExactNumberInfo::None))
);
assert_eq!(
get_data_type_by_alias_name("Float64"),
Some(DataType::Double)
Some(DataType::Double(ExactNumberInfo::None))
);
assert_eq!(
get_data_type_by_alias_name("FLOAT64"),
Some(DataType::Double)
Some(DataType::Double(ExactNumberInfo::None))
);
assert_eq!(
@@ -410,9 +411,9 @@ CREATE TABLE data_types (
Statement::CreateTable(c) => {
let expected = r#"CREATE TABLE data_types (
s STRING,
tt TEXT,
mt TEXT,
lt TEXT,
tt TINYTEXT,
mt MEDIUMTEXT,
lt LONGTEXT,
tint TINYINT,
sint SMALLINT,
i INT,