Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use the same interface #981

Merged
merged 1 commit into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion evadb/interfaces/relational/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from evadb.database import EvaDBDatabase, init_evadb_instance
from evadb.expression.tuple_value_expression import TupleValueExpression
from evadb.interfaces.relational.relation import EvaDBQuery
from evadb.interfaces.relational.utils import execute_statement, try_binding
from evadb.interfaces.relational.utils import try_binding
from evadb.models.server.response import Response
from evadb.models.storage.batch import Batch
from evadb.parser.alias import Alias
Expand All @@ -40,6 +40,7 @@
parse_show,
parse_table_clause,
)
from evadb.server.command_handler import execute_statement
from evadb.udfs.udf_bootstrap_queries import init_builtin_udfs
from evadb.utils.generic_utils import find_nearest_word, is_ray_enabled_and_installed
from evadb.utils.logging_manager import logger
Expand Down
2 changes: 1 addition & 1 deletion evadb/interfaces/relational/relation.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from evadb.interfaces.relational.utils import (
create_limit_expression,
create_star_expression,
execute_statement,
handle_select_clause,
sql_predicate_to_expresssion_tree,
sql_string_to_expresssion_list,
Expand All @@ -34,6 +33,7 @@
from evadb.parser.table_ref import JoinNode, TableRef
from evadb.parser.types import JoinType
from evadb.parser.utils import parse_sql_orderby_expr
from evadb.server.command_handler import execute_statement


class EvaDBQuery:
Expand Down
15 changes: 0 additions & 15 deletions evadb/interfaces/relational/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,9 @@

from evadb.binder.statement_binder import StatementBinder
from evadb.binder.statement_binder_context import StatementBinderContext
from evadb.database import EvaDBDatabase
from evadb.executor.plan_executor import PlanExecutor
from evadb.expression.abstract_expression import AbstractExpression
from evadb.expression.constant_value_expression import ConstantValueExpression
from evadb.expression.tuple_value_expression import TupleValueExpression
from evadb.models.storage.batch import Batch
from evadb.optimizer.plan_generator import PlanGenerator
from evadb.optimizer.statement_to_opr_converter import StatementToPlanConverter
from evadb.parser.select_statement import SelectStatement
from evadb.parser.statement import AbstractStatement
from evadb.parser.table_ref import TableRef
Expand Down Expand Up @@ -51,16 +46,6 @@ def sql_predicate_to_expresssion_tree(expr: str) -> AbstractExpression:
return parse_predicate_expression(expr)


def execute_statement(evadb: EvaDBDatabase, statement: AbstractStatement) -> Batch:
StatementBinder(StatementBinderContext(evadb.catalog)).bind(statement)
l_plan = StatementToPlanConverter().visit(statement)
p_plan = PlanGenerator(evadb).build(l_plan)
output = PlanExecutor(evadb, p_plan).execute_plan()
if output:
batch_list = list(output)
return Batch.concat(batch_list, copy=False)


def string_to_lateral_join(expr: str, alias: str):
return parse_lateral_join(expr, alias)

Expand Down
50 changes: 32 additions & 18 deletions evadb/server/command_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,37 @@
from evadb.optimizer.plan_generator import PlanGenerator
from evadb.optimizer.statement_to_opr_converter import StatementToPlanConverter
from evadb.parser.parser import Parser
from evadb.parser.statement import AbstractStatement
from evadb.parser.utils import SKIP_BINDER_AND_OPTIMIZER_STATEMENTS
from evadb.utils.logging_manager import logger
from evadb.utils.stats import Timer


def execute_statement(
evadb: EvaDBDatabase,
stmt: AbstractStatement,
do_not_raise_exceptions: bool = False,
do_not_print_exceptions: bool = False,
**kwargs
) -> Iterator[Batch]:
# For certain statements, we plan to omit binder and optimizer to keep the code
# clean. So, we handle such cases here and pass the statement directly to the
# executor.
plan_generator = kwargs.pop("plan_generator", PlanGenerator(evadb))
if not isinstance(stmt, SKIP_BINDER_AND_OPTIMIZER_STATEMENTS):
StatementBinder(StatementBinderContext(evadb.catalog)).bind(stmt)
l_plan = StatementToPlanConverter().visit(stmt)
p_plan = plan_generator.build(l_plan)
else:
p_plan = stmt
output = PlanExecutor(evadb, p_plan).execute_plan(
do_not_raise_exceptions, do_not_print_exceptions
)
if output:
batch_list = list(output)
return Batch.concat(batch_list, copy=False)


def execute_query(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference between execute_query, execute_query_fetch_all and execute_statement now? It seems that they all do the same thing. I think originally execute_query is returning a generator, which intends to be used to implement fetch_all, fetch_one, though we never implemented fetch_one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surpassing this comment as this is breaking the build, and we need to hot fix it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure the original design intension. execute_statement takes a statement as its argument so I just converted to an inner function of execute_query.

evadb: EvaDBDatabase,
query,
Expand All @@ -40,27 +66,17 @@ def execute_query(
Execute the query and return a result generator.
"""
query_compile_time = Timer()
plan_generator = kwargs.pop("plan_generator", PlanGenerator(evadb))

with query_compile_time:
stmt = Parser().parse(query)[0]

# For certain statements, we plan to omit binder and optimizer to keep the code
# clean. So, we handle such cases here and pass the statement directly to the
# executor.
if not isinstance(stmt, SKIP_BINDER_AND_OPTIMIZER_STATEMENTS):
StatementBinder(StatementBinderContext(evadb.catalog)).bind(stmt)
l_plan = StatementToPlanConverter().visit(stmt)
p_plan = plan_generator.build(l_plan)
else:
p_plan = stmt
output = PlanExecutor(evadb, p_plan).execute_plan(
do_not_raise_exceptions, do_not_print_exceptions
res_batch = execute_statement(
evadb, stmt, do_not_raise_exceptions, do_not_print_exceptions, **kwargs
)

if report_time is True:
query_compile_time.log_elapsed_time("Query Compile Time")

return output
return res_batch


def execute_query_fetch_all(
Expand All @@ -74,17 +90,15 @@ def execute_query_fetch_all(
"""
Execute the query and fetch all results into one Batch object.
"""
output = execute_query(
res_batch = execute_query(
evadb,
query,
report_time,
do_not_raise_exceptions,
do_not_print_exceptions,
**kwargs
)
if output:
batch_list = list(output)
return Batch.concat(batch_list, copy=False)
return res_batch


async def handle_request(evadb: EvaDBDatabase, client_writer, request_message):
Expand Down
8 changes: 8 additions & 0 deletions evadb/utils/generic_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,14 @@ def try_to_import_qdrant_client():
)


def is_qdrant_available() -> bool:
try:
try_to_import_qdrant_client()
return True
except ValueError: # noqa: E722
return False


##############################
## UTILS
##############################
Expand Down
3 changes: 2 additions & 1 deletion test/integration_tests/long/test_similarity.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# limitations under the License.
import os
import unittest
from test.markers import gpu_skip_marker
from test.markers import gpu_skip_marker, qdrant_skip_marker
from test.util import (
create_sample_image,
get_evadb_for_testing,
Expand Down Expand Up @@ -369,6 +369,7 @@ def test_end_to_end_index_scan_should_work_correctly_on_image_dataset(self):
self.assertEqual(res_batch.frames["testsimilarityimagedataset._row_id"][0], 5)

@gpu_skip_marker
@qdrant_skip_marker
def test_end_to_end_index_scan_should_work_correctly_on_image_dataset_qdrant(self):
create_index_query = """CREATE INDEX testFaissIndexImageDataset
ON testSimilarityImageDataset (DummyFeatureExtractor(data))
Expand Down
8 changes: 6 additions & 2 deletions test/markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@

import pytest

from evadb.utils.generic_utils import is_gpu_available, is_ludwig_available
from evadb.utils.generic_utils import (
is_gpu_available,
is_ludwig_available,
is_qdrant_available,
)

asyncio_skip_marker = pytest.mark.skipif(
sys.version_info < (3, 8), reason="Test case requires asyncio support"
)

qdrant_skip_marker = pytest.mark.skipif(
sys.version_info.minor == 11,
is_qdrant_available() is False,
reason="qdrant requires grcpio which is broken on 3.11",
)

Expand Down