diff --git a/mindsdb_sql_parser/lexer.py b/mindsdb_sql_parser/lexer.py index 9232efb..9663831 100644 --- a/mindsdb_sql_parser/lexer.py +++ b/mindsdb_sql_parser/lexer.py @@ -53,7 +53,7 @@ class MindsDBLexer(Lexer): GROUP_BY, HAVING, ORDER_BY, STAR, FOR, UPDATE, - JOIN, INNER, OUTER, CROSS, LEFT, RIGHT, ON, + JOIN, INNER, OUTER, CROSS, LEFT, RIGHT, ON, ASOF, UNION, ALL, INTERSECT, EXCEPT, @@ -234,6 +234,7 @@ class MindsDBLexer(Lexer): CROSS = r'\bCROSS\b' LEFT = r'\bLEFT\b' RIGHT = r'\bRIGHT\b' + ASOF = r'\bASOF\b' # UNION diff --git a/mindsdb_sql_parser/parser.py b/mindsdb_sql_parser/parser.py index 55cec41..7d8d6ae 100644 --- a/mindsdb_sql_parser/parser.py +++ b/mindsdb_sql_parser/parser.py @@ -1283,6 +1283,9 @@ def from_table(self, p): 'OUTER JOIN', 'LEFT OUTER JOIN', 'FULL OUTER JOIN', + 'ASOF JOIN', + 'ASOF LEFT JOIN', + 'LEFT ASOF JOIN', ) def join_clause(self, p): return ' '.join([x for x in p]) diff --git a/tests/test_base_sql/test_select_structure.py b/tests/test_base_sql/test_select_structure.py index d9acfc4..6bb334d 100644 --- a/tests/test_base_sql/test_select_structure.py +++ b/tests/test_base_sql/test_select_structure.py @@ -1236,3 +1236,22 @@ def test_mixed_join(self): ast = parse_sql(query) assert str(ast) == str(expected_ast) assert ast.to_tree() == expected_ast.to_tree() + + def test_asof_join(self): + for join_type in ('asof join', 'left asof join', 'asof left join'): + query = f''' + select * from table1 a + {join_type} table2 b on a.x = b.y + ''' + expected_ast = Select( + targets=[Star()], + from_table=Join( + left=Identifier('table1', alias=Identifier('a')), + right=Identifier('table2', alias=Identifier('b')), + condition=BinaryOperation(op='=', args=[Identifier('a.x'), Identifier('b.y')]), + join_type=join_type, + ) + ) + ast = parse_sql(query) + assert str(ast) == str(expected_ast) + assert ast.to_tree() == expected_ast.to_tree()