Skip to content

Commit

Permalink
update binder and parser
Browse files Browse the repository at this point in the history
  • Loading branch information
jiashenC committed Aug 21, 2023
1 parent e8f3221 commit bb3e372
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 4 deletions.
64 changes: 63 additions & 1 deletion evadb/binder/binder_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
is_video_table,
)
from evadb.catalog.models.table_catalog import TableCatalogEntry
from evadb.catalog.models.column_catalog import ColumnCatalogEntry

if TYPE_CHECKING:
from evadb.binder.statement_binder_context import StatementBinderContext
Expand All @@ -37,6 +38,7 @@
from evadb.parser.create_statement import ColumnDefinition
from evadb.parser.table_ref import TableInfo, TableRef
from evadb.utils.logging_manager import logger
from evadb.third_party.databases.interface import get_database_handler


class BinderError(Exception):
Expand All @@ -45,7 +47,7 @@ class BinderError(Exception):

def bind_table_info(
catalog: CatalogManager, table_info: TableInfo
) -> TableCatalogEntry:
):
"""
Uses catalog to bind the table information .
Expand All @@ -56,6 +58,66 @@ def bind_table_info(
Returns:
TableCatalogEntry - corresponding table catalog entry for the input table info
"""
if table_info.database_name is not None:
bind_native_table_info(catalog, table_info)
else:
bind_evadb_table_info(catalog, table_info)


def bind_native_table_info(
catalog: CatalogManager, table_info: TableInfo
):
db_catalog_entry = catalog.get_database_catalog_entry(table_info.database_name)

if db_catalog_entry is not None:
handler = get_database_handler(db_catalog_entry.engine)

# Get table definition.
resp = handler.get_tables()
if resp.error is not None:
error = "There is no table in data source {}. Create the table using native query.".format(
table_info.database_name,
)
logger.error(error)
raise BinderError(error)

# Check table existance.
table_df = resp.data
if table_info.table_name not in table_df["table_name"].values:
error = "Table {} does not exist in data source {}. Create the table using native query.".format(
table_info.table_name,
table_info.database_name,
)
logger.error(error)
raise BinderError(error)

# Assemble columns.
column_df = handler.get_columns(table_info.table_name).data
column_list = []
for column_name in column_df["column_name"]:
column_list.append(
ColumnCatalogEntry(column_name)
)

# Assemble table.
table_catalog_entry = TableCatalogEntry(
name=table_info.table_name,
table_type=TableType.NATIVE_DATA,
columns=column_list,
)
table_info.table_obj = table_catalog_entry

else:
error = "{} data source does not exist. Create the new database source using CREATE DATABASE.".format(
table_info.database_name,
)
logger.error(error)
raise BinderError(error)


def bind_evadb_table_info(
catalog: CatalogManager, table_info: TableInfo
):
obj = catalog.get_table_catalog_entry(
table_info.table_name,
table_info.database_name,
Expand Down
4 changes: 4 additions & 0 deletions evadb/catalog/catalog_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ class TableType(EvaDBEnum):
# cannot be accessed/modified directly by user
SYSTEM_STRUCTURED_DATA # noqa: F821

# Reserved for tables that are stored in native
# database backend.
NATIVE_DATA


class ColumnType(EvaDBEnum):
BOOLEAN # noqa: F821
Expand Down
12 changes: 9 additions & 3 deletions evadb/parser/lark_visitor/_common_clauses_ids.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,21 @@

class CommonClauses:
def table_name(self, tree):
table_name = self.visit(tree.children[0])
database_name, table_name = self.visit(tree.children[0])
if table_name is not None:
return TableInfo(table_name=table_name)
return TableInfo(table_name=table_name, database_name=database_name)
else:
error = "Invalid Table Name"
logger.error(error)

def full_id(self, tree):
return self.visit(tree.children[0])
if len(tree.children) == 1:
# Table only
return [None, self.visit(tree.children[0])]
elif len(tree.children) == 2:
# Data source and table
# Ex. DemoDB.TestTable
return [self.visit(tree.children[0]), self.visit(tree.children[1])]

def uid(self, tree):
return self.visit(tree.children[0])
Expand Down
18 changes: 18 additions & 0 deletions test/parser/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,24 @@ class ParserTests(unittest.TestCase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def test_select_from_data_source(self):
parser = Parser()

query = "SELECT * FROM DemoDB.DemoTable"
evadb_stmt_list = parser.parse(query)

# check stmt itself
self.assertIsInstance(evadb_stmt_list, list)
self.assertEqual(len(evadb_stmt_list), 1)
self.assertEqual(evadb_stmt_list[0].stmt_type, StatementType.SELECT)

# from_table
select_stmt = evadb_stmt_list[0]
self.assertIsNotNone(select_stmt.from_table)
self.assertIsInstance(select_stmt.from_table, TableRef)
self.assertEqual(select_stmt.from_table.table.table_name, "DemoTable")
self.assertEqual(select_stmt.from_table.table.database_name, "DemoDB")

def test_use_statement(self):
parser = Parser()

Expand Down

0 comments on commit bb3e372

Please sign in to comment.