• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

georgia-tech-db / eva / #789

18 Sep 2023 04:32PM UTC coverage: 74.685% (-5.7%) from 80.421%
#789

push

circle-ci

Jiashen Cao
reformat

8842 of 11839 relevant lines covered (74.69%)

0.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.05
/evadb/executor/executor_utils.py
1
# coding=utf-8
2
# Copyright 2018-2023 EvaDB
3
#
4
# Licensed under the Apache License, Version 2.0 (the "License");
5
# you may not use this file except in compliance with the License.
6
# You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
import glob
1✔
16
import os
1✔
17
from pathlib import Path
1✔
18
from typing import TYPE_CHECKING, Generator, List
1✔
19

20
from evadb.catalog.catalog_utils import xform_column_definitions_to_catalog_entries
1✔
21
from evadb.catalog.models.utils import TableCatalogEntry
1✔
22
from evadb.parser.create_statement import ColumnDefinition
1✔
23

24
if TYPE_CHECKING:
25
    from evadb.catalog.catalog_manager import CatalogManager
26

27
from evadb.catalog.catalog_type import TableType, VectorStoreType
1✔
28
from evadb.expression.abstract_expression import AbstractExpression
1✔
29
from evadb.expression.function_expression import FunctionExpression
1✔
30
from evadb.models.storage.batch import Batch
1✔
31
from evadb.parser.table_ref import TableInfo
1✔
32
from evadb.parser.types import FileFormatType
1✔
33
from evadb.readers.document.registry import SUPPORTED_TYPES
1✔
34
from evadb.utils.generic_utils import try_to_import_cv2
1✔
35
from evadb.utils.logging_manager import logger
1✔
36

37

38
class ExecutorError(Exception):
1✔
39
    pass
1✔
40

41

42
def apply_project(
1✔
43
    batch: Batch, project_list: List[AbstractExpression], catalog: "CatalogManager"
44
):
45
    if not batch.empty() and project_list:
1✔
46
        batches = [expr.evaluate(batch) for expr in project_list]
1✔
47
        batch = Batch.merge_column_wise(batches)
1✔
48

49
        # persist stats of function expression
50
        for expr in project_list:
1✔
51
            for func_expr in expr.find_all(FunctionExpression):
1✔
52
                if func_expr.function_obj and func_expr._stats:
1✔
53
                    function_id = func_expr.function_obj.row_id
1✔
54
                    catalog.upsert_function_cost_catalog_entry(
1✔
55
                        function_id,
56
                        func_expr.function_obj.name,
57
                        func_expr._stats.prev_cost,
58
                    )
59
    return batch
1✔
60

61

62
def apply_predicate(
1✔
63
    batch: Batch, predicate: AbstractExpression, catalog: "CatalogManager"
64
) -> Batch:
65
    if not batch.empty() and predicate is not None:
1✔
66
        outcomes = predicate.evaluate(batch)
1✔
67
        batch.drop_zero(outcomes)
1✔
68
        batch.reset_index()
1✔
69

70
        # persist stats of function expression
71
        for func_expr in predicate.find_all(FunctionExpression):
1✔
72
            if func_expr.function_obj and func_expr._stats:
1✔
73
                function_id = func_expr.function_obj.row_id
1✔
74
                catalog.upsert_function_cost_catalog_entry(
1✔
75
                    function_id, func_expr.function_obj.name, func_expr._stats.prev_cost
76
                )
77
    return batch
1✔
78

79

80
def handle_if_not_exists(
1✔
81
    catalog: "CatalogManager", table_info: TableInfo, if_not_exist=False
82
):
83
    # Table exists
84
    if catalog.check_table_exists(
1✔
85
        table_info.table_name,
86
        table_info.database_name,
87
    ):
88
        err_msg = "Table: {} already exists".format(table_info)
×
89
        if if_not_exist:
×
90
            logger.warn(err_msg)
×
91
            return True
×
92
        else:
93
            logger.error(err_msg)
×
94
            raise ExecutorError(err_msg)
95
    # Table does not exist
96
    else:
97
        return False
1✔
98

99

100
def validate_image(image_path: Path) -> bool:
1✔
101
    try:
×
102
        try_to_import_cv2()
×
103
        import cv2
×
104

105
        data = cv2.imread(str(image_path))
×
106
        return data is not None
×
107
    except Exception as e:
108
        logger.warning(
109
            f"Unexpected Exception {e} occurred while reading image file {image_path}"
110
        )
111
        return False
112

113

114
def iter_path_regex(path_regex: Path) -> Generator[str, None, None]:
1✔
115
    return glob.iglob(os.path.expanduser(path_regex), recursive=True)
1✔
116

117

118
def validate_video(video_path: Path) -> bool:
1✔
119
    try:
1✔
120
        try_to_import_cv2()
1✔
121
        import cv2
1✔
122

123
        vid = cv2.VideoCapture(str(video_path))
1✔
124
        if not vid.isOpened():
1✔
125
            return False
×
126
        return True
1✔
127
    except Exception as e:
128
        logger.warning(
129
            f"Unexpected Exception {e} occurred while reading video file {video_path}"
130
        )
131

132

133
def validate_document(doc_path: Path) -> bool:
1✔
134
    return doc_path.suffix in SUPPORTED_TYPES
×
135

136

137
def validate_pdf(doc_path: Path) -> bool:
1✔
138
    return doc_path.suffix == ".pdf"
×
139

140

141
def validate_media(file_path: Path, media_type: FileFormatType) -> bool:
1✔
142
    if media_type == FileFormatType.VIDEO:
1✔
143
        return validate_video(file_path)
1✔
144
    elif media_type == FileFormatType.IMAGE:
×
145
        return validate_image(file_path)
×
146
    elif media_type == FileFormatType.DOCUMENT:
×
147
        return validate_document(file_path)
×
148
    elif media_type == FileFormatType.PDF:
×
149
        return validate_pdf(file_path)
×
150
    else:
151
        raise ValueError(f"Unsupported Media type {str(media_type)}")
152

153

154
def handle_vector_store_params(
1✔
155
    vector_store_type: VectorStoreType, index_path: str
156
) -> dict:
157
    """Handle vector store parameters based on the vector store type and index path.
158

159
    Args:
160
        vector_store_type (VectorStoreType): The type of vector store.
161
        index_path (str): The path to store the index.
162

163
    Returns:
164
        dict: Dictionary containing the appropriate vector store parameters.
165

166

167
    Raises:
168
        ValueError: If the vector store type in the node is not supported.
169
    """
170
    if vector_store_type == VectorStoreType.FAISS:
×
171
        return {"index_path": index_path}
×
172
    elif vector_store_type == VectorStoreType.QDRANT:
×
173
        return {"index_db": str(Path(index_path).parent)}
×
174
    else:
175
        raise ValueError("Unsupported vector store type: {}".format(vector_store_type))
176

177

178
def create_table_catalog_entry_for_native_table(
1✔
179
    table_info: TableInfo, column_list: List[ColumnDefinition]
180
):
181
    column_catalog_entires = xform_column_definitions_to_catalog_entries(column_list)
×
182

183
    # Assemble table.
184
    table_catalog_entry = TableCatalogEntry(
×
185
        name=table_info.table_name,
186
        file_url=None,
187
        table_type=TableType.NATIVE_DATA,
188
        columns=column_catalog_entires,
189
        database_name=table_info.database_name,
190
    )
191
    return table_catalog_entry
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc