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

georgia-tech-db / eva / #754

04 Sep 2023 09:54PM UTC coverage: 74.807% (-5.5%) from 80.336%
#754

push

circle-ci

jiashenC
update case

8727 of 11666 relevant lines covered (74.81%)

0.75 hits per line

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

93.18
/evadb/parser/lark_visitor/_create_statements.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

16
from lark import Tree
1✔
17

18
from evadb.catalog.catalog_type import ColumnType, NdArrayType, VectorStoreType
1✔
19
from evadb.expression.tuple_value_expression import TupleValueExpression
1✔
20
from evadb.parser.create_index_statement import CreateIndexStatement
1✔
21
from evadb.parser.create_statement import (
1✔
22
    ColConstraintInfo,
23
    ColumnDefinition,
24
    CreateDatabaseStatement,
25
    CreateTableStatement,
26
)
27
from evadb.parser.table_ref import TableRef
1✔
28
from evadb.parser.types import ColumnConstraintEnum
1✔
29

30

31
##################################################################
32
# CREATE STATEMENTS
33
##################################################################
34
class CreateTable:
1✔
35
    def create_table(self, tree):
1✔
36
        table_info = None
1✔
37
        if_not_exists = False
1✔
38
        create_definitions = []
1✔
39
        query = None
1✔
40

41
        for child in tree.children:
1✔
42
            if isinstance(child, Tree):
1✔
43
                if child.data == "if_not_exists":
1✔
44
                    if_not_exists = True
1✔
45
                elif child.data == "table_name":
1✔
46
                    table_info = self.visit(child)
1✔
47
                elif child.data == "create_definitions":
1✔
48
                    create_definitions = self.visit(child)
1✔
49
                elif child.data == "simple_select":
1✔
50
                    query = self.visit(child)
1✔
51

52
        create_stmt = CreateTableStatement(
1✔
53
            table_info, if_not_exists, create_definitions, query=query
54
        )
55
        return create_stmt
1✔
56

57
    def create_definitions(self, tree):
1✔
58
        column_definitions = []
1✔
59
        for child in tree.children:
1✔
60
            if isinstance(child, Tree):
1✔
61
                create_definition = None
1✔
62
                if child.data == "column_declaration":
1✔
63
                    create_definition = self.visit(child)
1✔
64
                column_definitions.append(create_definition)
1✔
65

66
        return column_definitions
1✔
67

68
    def column_declaration(self, tree):
1✔
69
        column_name = None
1✔
70
        data_type = None
1✔
71
        array_type = None
1✔
72
        dimensions = None
1✔
73
        column_constraint_information = None
1✔
74

75
        for child in tree.children:
1✔
76
            if isinstance(child, Tree):
1✔
77
                if child.data == "uid":
1✔
78
                    column_name = self.visit(child)
1✔
79
                elif child.data == "column_definition":
1✔
80
                    (
1✔
81
                        data_type,
82
                        array_type,
83
                        dimensions,
84
                        column_constraint_information,
85
                    ) = self.visit(child)
86

87
        if column_name is not None:
1✔
88
            return ColumnDefinition(
1✔
89
                column_name,
90
                data_type,
91
                array_type,
92
                dimensions,
93
                column_constraint_information,
94
            )
95

96
    def column_definition(self, tree):
1✔
97
        data_type = None
1✔
98
        array_type = None
1✔
99
        dimensions = None
1✔
100
        column_constraint_information = ColConstraintInfo()
1✔
101
        not_null_set = False
1✔
102

103
        for child in tree.children:
1✔
104
            if isinstance(child, Tree):
1✔
105
                if child.data.endswith("data_type"):
1✔
106
                    data_type, array_type, dimensions = self.visit(child)
1✔
107
                elif child.data.endswith("column_constraint"):
1✔
108
                    return_type = self.visit(child)
1✔
109
                    if return_type == ColumnConstraintEnum.UNIQUE:
1✔
110
                        column_constraint_information.unique = True
1✔
111
                        column_constraint_information.nullable = False
1✔
112
                        not_null_set = True
1✔
113
                    elif return_type == ColumnConstraintEnum.NOTNULL:
×
114
                        column_constraint_information.nullable = False
×
115
                        not_null_set = True
×
116

117
        if not not_null_set:
1✔
118
            column_constraint_information.nullable = True
1✔
119

120
        return data_type, array_type, dimensions, column_constraint_information
1✔
121

122
    def unique_key_column_constraint(self, tree):
1✔
123
        return ColumnConstraintEnum.UNIQUE
1✔
124

125
    def null_column_constraint(self, tree):
1✔
126
        return ColumnConstraintEnum.NOTNULL
×
127

128
    def simple_data_type(self, tree):
1✔
129
        data_type = None
×
130
        array_type = None
×
131
        dimensions = []
×
132

133
        token = tree.children[0]
×
134
        if str.upper(token) == "BOOLEAN":
×
135
            data_type = ColumnType.BOOLEAN
×
136

137
        return data_type, array_type, dimensions
×
138

139
    def integer_data_type(self, tree):
1✔
140
        data_type = None
1✔
141
        array_type = None
1✔
142
        dimensions = []
1✔
143

144
        token = tree.children[0]
1✔
145
        if str.upper(token) == "INTEGER":
1✔
146
            data_type = ColumnType.INTEGER
1✔
147

148
        return data_type, array_type, dimensions
1✔
149

150
    def dimension_data_type(self, tree):
1✔
151
        data_type = None
1✔
152
        array_type = None
1✔
153
        dimensions = []
1✔
154

155
        token = tree.children[0]
1✔
156
        if str.upper(token) == "FLOAT":
1✔
157
            data_type = ColumnType.FLOAT
1✔
158
            dimensions = self.visit(tree.children[1])
1✔
159
        elif str.upper(token) == "TEXT":
1✔
160
            data_type = ColumnType.TEXT
1✔
161
            dimensions = self.visit(tree.children[1])
1✔
162

163
        return data_type, array_type, dimensions
1✔
164

165
    def array_data_type(self, tree):
1✔
166
        data_type = ColumnType.NDARRAY
1✔
167
        array_type = NdArrayType.ANYTYPE
1✔
168
        dimensions = None
1✔
169

170
        for child in tree.children:
1✔
171
            if isinstance(child, Tree):
1✔
172
                if child.data == "array_type":
1✔
173
                    array_type = self.visit(child)
1✔
174
                elif child.data == "length_dimension_list":
1✔
175
                    dimensions = self.visit(child)
1✔
176

177
        return data_type, array_type, dimensions
1✔
178

179
    def any_data_type(self, tree):
1✔
180
        return ColumnType.ANY, None, []
1✔
181

182
    def array_type(self, tree):
1✔
183
        array_type = None
1✔
184

185
        token = tree.children[0]
1✔
186
        if str.upper(token) == "INT8":
1✔
187
            array_type = NdArrayType.INT8
×
188
        elif str.upper(token) == "UINT8":
1✔
189
            array_type = NdArrayType.UINT8
1✔
190
        elif str.upper(token) == "INT16":
1✔
191
            array_type = NdArrayType.INT16
1✔
192
        elif str.upper(token) == "INT32":
1✔
193
            array_type = NdArrayType.INT32
1✔
194
        elif str.upper(token) == "INT64":
1✔
195
            array_type = NdArrayType.INT64
1✔
196
        elif str.upper(token) == "UNICODE":
1✔
197
            array_type = NdArrayType.UNICODE
1✔
198
        elif str.upper(token) == "BOOLEAN":
1✔
199
            array_type = NdArrayType.BOOL
1✔
200
        elif str.upper(token) == "FLOAT32":
1✔
201
            array_type = NdArrayType.FLOAT32
1✔
202
        elif str.upper(token) == "FLOAT64":
1✔
203
            array_type = NdArrayType.FLOAT64
1✔
204
        elif str.upper(token) == "DECIMAL":
1✔
205
            array_type = NdArrayType.DECIMAL
1✔
206
        elif str.upper(token) == "STR":
1✔
207
            array_type = NdArrayType.STR
1✔
208
        elif str.upper(token) == "DATETIME":
1✔
209
            array_type = NdArrayType.DATETIME
1✔
210
        elif str.upper(token) == "ANYTYPE":
1✔
211
            array_type = NdArrayType.ANYTYPE
1✔
212
        return array_type
1✔
213

214
    def dimension_helper(self, tree):
1✔
215
        dimensions = []
1✔
216
        for child in tree.children:
1✔
217
            if isinstance(child, Tree):
1✔
218
                if child.data == "decimal_literal":
1✔
219
                    decimal = self.visit(child)
1✔
220
                    dimensions.append(decimal)
1✔
221
        return tuple(dimensions)
1✔
222

223
    def length_one_dimension(self, tree):
1✔
224
        dimensions = self.dimension_helper(tree)
1✔
225
        return dimensions
1✔
226

227
    def length_two_dimension(self, tree):
1✔
228
        dimensions = self.dimension_helper(tree)
1✔
229
        return dimensions
1✔
230

231
    def length_dimension_list(self, tree):
1✔
232
        dimensions = self.dimension_helper(tree)
1✔
233
        return dimensions
1✔
234

235
    def vector_store_type(self, tree):
1✔
236
        vector_store_type = None
1✔
237
        token = tree.children[1]
1✔
238

239
        if str.upper(token) == "FAISS":
1✔
240
            vector_store_type = VectorStoreType.FAISS
1✔
241
        elif str.upper(token) == "QDRANT":
×
242
            vector_store_type = VectorStoreType.QDRANT
×
243
        return vector_store_type
1✔
244

245
    # INDEX CREATION
246
    def create_index(self, tree):
1✔
247
        index_name = None
1✔
248
        table_name = None
1✔
249
        vector_store_type = None
1✔
250
        index_elem = None
1✔
251

252
        for child in tree.children:
1✔
253
            if isinstance(child, Tree):
1✔
254
                if child.data == "uid":
1✔
255
                    index_name = self.visit(child)
1✔
256
                elif child.data == "table_name":
1✔
257
                    table_name = self.visit(child)
1✔
258
                    table_ref = TableRef(table_name)
1✔
259
                elif child.data == "vector_store_type":
1✔
260
                    vector_store_type = self.visit(child)
1✔
261
                elif child.data == "index_elem":
1✔
262
                    index_elem = self.visit(child)
1✔
263

264
        # Parse either a single function call or column list.
265
        col_list, function = None, None
1✔
266
        if not isinstance(index_elem, list):
1✔
267
            function = index_elem
1✔
268

269
            # Traverse to the tuple value expression.
270
            while not isinstance(index_elem, TupleValueExpression):
1✔
271
                index_elem = index_elem.children[0]
1✔
272
            index_elem = [index_elem]
1✔
273

274
        col_list = [
1✔
275
            ColumnDefinition(tv_expr.name, None, None, None) for tv_expr in index_elem
276
        ]
277

278
        return CreateIndexStatement(
1✔
279
            index_name, table_ref, col_list, vector_store_type, function
280
        )
281

282

283
class CreateDatabase:
1✔
284
    def create_database(self, tree):
1✔
285
        database_name = None
1✔
286
        if_not_exists = False
1✔
287
        engine = None
1✔
288
        param_dict = {}
1✔
289

290
        for child in tree.children:
1✔
291
            if isinstance(child, Tree):
1✔
292
                if child.data == "if_not_exists":
1✔
293
                    if_not_exists = True
×
294
                elif child.data == "uid":
1✔
295
                    database_name = self.visit(child)
1✔
296
                elif child.data == "create_database_engine_clause":
1✔
297
                    engine, param_dict = self.visit(child)
1✔
298

299
        create_stmt = CreateDatabaseStatement(
1✔
300
            database_name, if_not_exists, engine, param_dict
301
        )
302
        return create_stmt
1✔
303

304
    def create_database_engine_clause(self, tree):
1✔
305
        engine = None
1✔
306
        param_dict = {}
1✔
307
        for child in tree.children:
1✔
308
            if isinstance(child, Tree):
1✔
309
                if child.data == "string_literal":
1✔
310
                    engine = self.visit(child).value
1✔
311
                elif child.data == "colon_param_dict":
1✔
312
                    param_dict = self.visit(child)
1✔
313

314
        return engine, param_dict
1✔
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

© 2025 Coveralls, Inc