Merge pull request #32 from cswinter/like

Add LIKE operator
This commit is contained in:
Andy Grove 2018-12-16 13:54:00 -07:00 committed by GitHub
commit 24af049930
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 28 additions and 4 deletions

View file

@ -11,7 +11,7 @@ impl Dialect for GenericSqlDialect {
STORED, CSV, PARQUET, LOCATION, WITH, WITHOUT, HEADER, ROW, // SQL types STORED, CSV, PARQUET, LOCATION, WITH, WITHOUT, HEADER, ROW, // SQL types
CHAR, CHARACTER, VARYING, LARGE, OBJECT, VARCHAR, CLOB, BINARY, VARBINARY, BLOB, FLOAT, CHAR, CHARACTER, VARYING, LARGE, OBJECT, VARCHAR, CLOB, BINARY, VARBINARY, BLOB, FLOAT,
REAL, DOUBLE, PRECISION, INT, INTEGER, SMALLINT, BIGINT, NUMERIC, DECIMAL, DEC, REAL, DOUBLE, PRECISION, INT, INTEGER, SMALLINT, BIGINT, NUMERIC, DECIMAL, DEC,
BOOLEAN, DATE, TIME, TIMESTAMP, CASE, WHEN, THEN, ELSE, END, BOOLEAN, DATE, TIME, TIMESTAMP, CASE, WHEN, THEN, ELSE, END, LIKE,
]; ];
} }

View file

@ -14,7 +14,7 @@ impl Dialect for PostgreSqlDialect {
DOUBLE, PRECISION, INT, INTEGER, SMALLINT, BIGINT, NUMERIC, DECIMAL, DEC, BOOLEAN, DOUBLE, PRECISION, INT, INTEGER, SMALLINT, BIGINT, NUMERIC, DECIMAL, DEC, BOOLEAN,
DATE, TIME, TIMESTAMP, VALUES, DEFAULT, ZONE, REGCLASS, TEXT, BYTEA, TRUE, FALSE, COPY, DATE, TIME, TIMESTAMP, VALUES, DEFAULT, ZONE, REGCLASS, TEXT, BYTEA, TRUE, FALSE, COPY,
STDIN, PRIMARY, KEY, UNIQUE, UUID, ADD, CONSTRAINT, FOREIGN, REFERENCES, STDIN, PRIMARY, KEY, UNIQUE, UUID, ADD, CONSTRAINT, FOREIGN, REFERENCES,
CASE, WHEN, THEN, ELSE, END, CASE, WHEN, THEN, ELSE, END, LIKE,
]; ];
} }

View file

@ -14,6 +14,7 @@ pub enum SQLOperator {
NotEq, NotEq,
And, And,
Or, Or,
Like,
} }
impl ToString for SQLOperator { impl ToString for SQLOperator {
@ -32,6 +33,7 @@ impl ToString for SQLOperator {
SQLOperator::NotEq => "!=".to_string(), SQLOperator::NotEq => "!=".to_string(),
SQLOperator::And => "AND".to_string(), SQLOperator::And => "AND".to_string(),
SQLOperator::Or => "OR".to_string(), SQLOperator::Or => "OR".to_string(),
SQLOperator::Like => "LIKE".to_string(),
} }
} }
} }

View file

@ -18,7 +18,7 @@ use super::dialect::Dialect;
use super::sqlast::*; use super::sqlast::*;
use super::sqltokenizer::*; use super::sqltokenizer::*;
use chrono::{ use chrono::{
offset::{FixedOffset}, offset::FixedOffset,
DateTime, NaiveDate, NaiveDateTime, NaiveTime, DateTime, NaiveDate, NaiveDateTime, NaiveTime,
}; };
@ -334,6 +334,7 @@ impl Parser {
&Token::Mod => Ok(SQLOperator::Modulus), &Token::Mod => Ok(SQLOperator::Modulus),
&Token::Keyword(ref k) if k == "AND" => Ok(SQLOperator::And), &Token::Keyword(ref k) if k == "AND" => Ok(SQLOperator::And),
&Token::Keyword(ref k) if k == "OR" => Ok(SQLOperator::Or), &Token::Keyword(ref k) if k == "OR" => Ok(SQLOperator::Or),
&Token::Keyword(ref k) if k == "LIKE" => Ok(SQLOperator::Like),
_ => parser_err!(format!("Unsupported SQL operator {:?}", tok)), _ => parser_err!(format!("Unsupported SQL operator {:?}", tok)),
} }
} }
@ -355,6 +356,7 @@ impl Parser {
&Token::Keyword(ref k) if k == "OR" => Ok(5), &Token::Keyword(ref k) if k == "OR" => Ok(5),
&Token::Keyword(ref k) if k == "AND" => Ok(10), &Token::Keyword(ref k) if k == "AND" => Ok(10),
&Token::Keyword(ref k) if k == "IS" => Ok(15), &Token::Keyword(ref k) if k == "IS" => Ok(15),
&Token::Keyword(ref k )if k == "LIKE" => Ok(20),
&Token::Eq | &Token::Lt | &Token::LtEq | &Token::Neq | &Token::Gt | &Token::GtEq => { &Token::Eq | &Token::Lt | &Token::LtEq | &Token::Neq | &Token::Gt | &Token::GtEq => {
Ok(20) Ok(20)
} }

View file

@ -23,7 +23,7 @@ fn parse_simple_select() {
fn parse_sql(sql: &str) -> ASTNode { fn parse_sql(sql: &str) -> ASTNode {
let dialect = AnsiSqlDialect {}; let dialect = AnsiSqlDialect {};
let mut tokenizer = Tokenizer::new(&dialect,&sql, ); let mut tokenizer = Tokenizer::new(&dialect, &sql);
let tokens = tokenizer.tokenize().unwrap(); let tokens = tokenizer.tokenize().unwrap();
let mut parser = Parser::new(tokens); let mut parser = Parser::new(tokens);
let ast = parser.parse().unwrap(); let ast = parser.parse().unwrap();

View file

@ -730,3 +730,23 @@ fn parser(sql: &str) -> Parser {
debug!("tokens: {:#?}", tokens); debug!("tokens: {:#?}", tokens);
Parser::new(tokens) Parser::new(tokens)
} }
#[test]
fn parse_like() {
let sql = String::from("SELECT * FROM customers WHERE name LIKE '%a'");
let ast = parse_sql(&sql);
assert_eq!(sql, ast.to_string());
match ast {
ASTNode::SQLSelect { selection, .. } => {
assert_eq!(
ASTNode::SQLBinaryExpr {
left: Box::new(ASTNode::SQLIdentifier("name".to_string())),
op: SQLOperator::Like,
right: Box::new(ASTNode::SQLValue(Value::SingleQuotedString("%a".to_string()))),
},
*selection.unwrap()
);
}
_ => assert!(false),
}
}