mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-25 01:10:37 +00:00
fix: unused table options (#2267)
* fix: unused table options keys * refactor: simplify validate table options * chore: Add newlines --------- Co-authored-by: Yingwen <realevenyag@gmail.com>
This commit is contained in:
@@ -19,6 +19,7 @@ once_cell.workspace = true
|
||||
regex.workspace = true
|
||||
snafu = { version = "0.7", features = ["backtraces"] }
|
||||
sqlparser.workspace = true
|
||||
table = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
common-datasource = { workspace = true }
|
||||
|
||||
@@ -103,6 +103,9 @@ pub enum Error {
|
||||
source: datatypes::error::Error,
|
||||
},
|
||||
|
||||
#[snafu(display("Invalid table option key: {}", key))]
|
||||
InvalidTableOption { key: String, location: Location },
|
||||
|
||||
#[snafu(display("Failed to serialize column default constraint, source: {}", source))]
|
||||
SerializeColumnDefaultConstraint {
|
||||
location: Location,
|
||||
@@ -168,7 +171,8 @@ impl ErrorExt for Error {
|
||||
| ColumnTypeMismatch { .. }
|
||||
| InvalidTableName { .. }
|
||||
| InvalidSqlValue { .. }
|
||||
| TimestampOverflow { .. } => StatusCode::InvalidArguments,
|
||||
| TimestampOverflow { .. }
|
||||
| InvalidTableOption { .. } => StatusCode::InvalidArguments,
|
||||
|
||||
SerializeColumnDefaultConstraint { source, .. } => source.status_code(),
|
||||
ConvertToGrpcDataType { source, .. } => source.status_code(),
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use common_catalog::consts::default_engine;
|
||||
use itertools::Itertools;
|
||||
@@ -24,11 +25,12 @@ use sqlparser::keywords::ALL_KEYWORDS;
|
||||
use sqlparser::parser::IsOptional::Mandatory;
|
||||
use sqlparser::parser::{Parser, ParserError};
|
||||
use sqlparser::tokenizer::{Token, TokenWithLocation, Word};
|
||||
use table::requests::valid_table_option;
|
||||
|
||||
use crate::ast::{ColumnDef, Ident, TableConstraint, Value as SqlValue};
|
||||
use crate::error::{
|
||||
self, InvalidColumnOptionSnafu, InvalidTimeIndexSnafu, MissingTimeIndexSnafu, Result,
|
||||
SyntaxSnafu,
|
||||
self, InvalidColumnOptionSnafu, InvalidTableOptionSnafu, InvalidTimeIndexSnafu,
|
||||
MissingTimeIndexSnafu, Result, SyntaxSnafu,
|
||||
};
|
||||
use crate::parser::ParserContext;
|
||||
use crate::statements::create::{
|
||||
@@ -91,8 +93,15 @@ impl<'a> ParserContext<'a> {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
.collect::<HashMap<String, String>>();
|
||||
for key in options.keys() {
|
||||
ensure!(
|
||||
valid_table_option(key),
|
||||
InvalidTableOptionSnafu {
|
||||
key: key.to_string()
|
||||
}
|
||||
);
|
||||
}
|
||||
Ok(Statement::CreateExternalTable(CreateExternalTable {
|
||||
name: table_name,
|
||||
columns,
|
||||
@@ -149,7 +158,14 @@ impl<'a> ParserContext<'a> {
|
||||
.parser
|
||||
.parse_options(Keyword::WITH)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
|
||||
for option in options.iter() {
|
||||
ensure!(
|
||||
valid_table_option(&option.name.value),
|
||||
InvalidTableOptionSnafu {
|
||||
key: option.name.value.to_string()
|
||||
}
|
||||
);
|
||||
}
|
||||
let create_table = CreateTable {
|
||||
if_not_exists,
|
||||
name: table_name,
|
||||
@@ -807,6 +823,24 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::dialect::GreptimeDbDialect;
|
||||
|
||||
#[test]
|
||||
fn test_validate_external_table_options() {
|
||||
let sql = "CREATE EXTERNAL TABLE city (
|
||||
host string,
|
||||
ts int64,
|
||||
cpu float64 default 0,
|
||||
memory float64,
|
||||
TIME INDEX (ts),
|
||||
PRIMARY KEY(ts, host)
|
||||
) with(location='/var/data/city.csv',format='csv',foo='bar');";
|
||||
|
||||
let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {});
|
||||
assert!(matches!(
|
||||
result,
|
||||
Err(error::Error::InvalidTableOption { .. })
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_create_external_table() {
|
||||
struct Test<'a> {
|
||||
|
||||
@@ -222,6 +222,7 @@ pub struct CreateExternalTable {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::dialect::GreptimeDbDialect;
|
||||
use crate::error::Error::InvalidTableOption;
|
||||
use crate::parser::ParserContext;
|
||||
use crate::statements::statement::Statement;
|
||||
|
||||
@@ -319,4 +320,26 @@ ENGINE=mito
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_table_options() {
|
||||
let sql = r"create table if not exists demo(
|
||||
host string,
|
||||
ts bigint,
|
||||
cpu double default 0,
|
||||
memory double,
|
||||
TIME INDEX (ts),
|
||||
PRIMARY KEY(ts, host)
|
||||
)
|
||||
PARTITION BY RANGE COLUMNS (ts) (
|
||||
PARTITION r0 VALUES LESS THAN (5),
|
||||
PARTITION r1 VALUES LESS THAN (9),
|
||||
PARTITION r2 VALUES LESS THAN (MAXVALUE),
|
||||
)
|
||||
engine=mito
|
||||
with(regions=1, ttl='7d', hello='world');
|
||||
";
|
||||
let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {});
|
||||
assert!(matches!(result, Err(InvalidTableOption { .. })))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user