Skip to content

Commit 94e16aa

Browse files
authored
Merge pull request #183 from UncoderIO/gis-7887
update field tokens collection
2 parents 656b101 + 2dd3146 commit 94e16aa

File tree

14 files changed

+121
-66
lines changed

14 files changed

+121
-66
lines changed

uncoder-core/app/translator/core/models/functions/base.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from dataclasses import dataclass, field
44
from typing import TYPE_CHECKING, Optional, Union
55

6-
from app.translator.core.models.query_tokens.field import Alias, Field
6+
from app.translator.core.models.query_tokens.field import Alias, BaseFieldsGetter, Field
77
from app.translator.core.models.query_tokens.field_field import FieldField
88
from app.translator.core.models.query_tokens.field_value import FieldValue
99
from app.translator.core.models.query_tokens.identifier import Identifier
@@ -14,14 +14,25 @@
1414

1515

1616
@dataclass
17-
class Function:
17+
class Function(BaseFieldsGetter):
1818
name: str = None
1919
args: list[
2020
Union[Alias, Field, FieldField, FieldValue, FunctionValue, Keyword, Function, Identifier, int, str, bool]
2121
] = field(default_factory=list)
2222
alias: Optional[Alias] = None
2323
raw: str = ""
2424

25+
@property
26+
def fields(self) -> list[Field]:
27+
fields = []
28+
for arg in self.args:
29+
if isinstance(arg, Field):
30+
fields.append(arg)
31+
elif isinstance(arg, (BaseFieldsGetter, Function)):
32+
fields.extend(arg.fields)
33+
34+
return fields
35+
2536

2637
@dataclass
2738
class ParsedFunctions:

uncoder-core/app/translator/core/models/functions/bin.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@ class BinFunction(Function):
1919
span: Optional[Span] = None
2020
field: Optional[Field] = None
2121
bins: Optional[int] = None
22+
23+
@property
24+
def fields(self) -> list[Field]:
25+
return [self.field] if self.field else []

uncoder-core/app/translator/core/models/functions/eval.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,16 @@ class EvalArg:
1717
class EvalFunction(Function):
1818
name: str = FunctionType.eval
1919
args: list[EvalArg] = None
20+
21+
@property
22+
def fields(self) -> list[Field]:
23+
fields = []
24+
for arg in self.args:
25+
if isinstance(arg.field_, Field):
26+
fields.append(arg.field_)
27+
for el in arg.expression:
28+
if isinstance(el, Field):
29+
fields.append(el)
30+
if isinstance(el, Function):
31+
fields.extend(el.fields)
32+
return fields
Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
from dataclasses import Field, dataclass, field
1+
from dataclasses import dataclass, field
22
from typing import Union
33

44
from app.translator.core.custom_types.functions import FunctionType
55
from app.translator.core.models.functions.base import Function
6-
from app.translator.core.models.query_tokens.field import Alias, PredefinedField
6+
from app.translator.core.models.query_tokens.field import Alias, Field, PredefinedField
77

88

99
@dataclass
@@ -12,3 +12,16 @@ class GroupByFunction(Function):
1212
args: list[Function] = field(default_factory=list)
1313
by_clauses: list[Union[Alias, Field, PredefinedField]] = field(default_factory=list)
1414
filter_: Function = None
15+
16+
@property
17+
def fields(self) -> list[Field]:
18+
fields = []
19+
for arg in self.args:
20+
fields.extend(arg.fields)
21+
for by_clause in self.by_clauses:
22+
if isinstance(by_clause, Field):
23+
fields.append(by_clause)
24+
if self.filter_:
25+
fields.extend(self.filter_.fields)
26+
27+
return fields

uncoder-core/app/translator/core/models/functions/join.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
from app.translator.core.custom_types.functions import FunctionType
55
from app.translator.core.models.functions.base import Function
66
from app.translator.core.models.query_container import TokenizedQueryContainer
7-
from app.translator.core.models.query_tokens.field import Alias, Field
7+
from app.translator.core.models.query_tokens.field import Alias, BaseFieldsGetter, Field
8+
from app.translator.core.models.query_tokens.field_field import FieldField
9+
from app.translator.core.models.query_tokens.field_value import FieldValue
10+
from app.translator.core.models.query_tokens.function_value import FunctionValue
811
from app.translator.core.models.query_tokens.identifier import Identifier
912
from app.translator.tools.custom_enum import CustomEnum
1013

@@ -22,5 +25,14 @@ class JoinFunction(Function):
2225
alias: Alias = None
2326
type_: str = JoinType.inner
2427
tokenized_query_container: TokenizedQueryContainer = None
25-
condition: list[Union[Alias, Field, Identifier]] = field(default_factory=list)
28+
condition: list[Union[FieldField, FieldValue, FunctionValue, Identifier]] = field(default_factory=list)
2629
preset_log_source_str: str = None
30+
31+
@property
32+
def fields(self) -> list[Field]:
33+
fields = []
34+
for arg in self.condition:
35+
if isinstance(arg, BaseFieldsGetter):
36+
fields.extend(arg.fields)
37+
38+
return fields

uncoder-core/app/translator/core/models/functions/rename.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,11 @@ class RenameArg:
1515
class RenameFunction(Function):
1616
name: str = FunctionType.rename
1717
args: list[RenameArg] = None
18+
19+
@property
20+
def fields(self) -> list[Field]:
21+
fields = []
22+
for arg in self.args:
23+
fields.append(arg.field_)
24+
25+
return fields

uncoder-core/app/translator/core/models/functions/sort.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,15 @@ class SortLimitFunction(Function):
2424
name: str = FunctionType.sort_limit
2525
args: list[SortArg] = None
2626
limit: str = None
27+
28+
@property
29+
def fields(self) -> list[Field]:
30+
fields = []
31+
for arg in self.args:
32+
if isinstance(arg.field, Field):
33+
fields.append(arg.field)
34+
35+
if arg.function:
36+
fields.extend(arg.function.fields)
37+
38+
return fields

uncoder-core/app/translator/core/models/functions/union.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
from app.translator.core.custom_types.functions import FunctionType
44
from app.translator.core.models.functions.base import Function
55
from app.translator.core.models.query_container import TokenizedQueryContainer
6+
from app.translator.core.models.query_tokens.field import Field
67

78

89
@dataclass
910
class UnionFunction(Function):
1011
name: str = FunctionType.union
1112
tokenized_query_container: TokenizedQueryContainer = None
1213
preset_log_source_str: str = None
14+
15+
@property
16+
def fields(self) -> list[Field]:
17+
return []

uncoder-core/app/translator/core/models/query_tokens/field.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from abc import ABC, abstractmethod
12
from typing import Optional
23

34
from app.translator.core.mapping import DEFAULT_MAPPING_NAME, SourceMapping
@@ -37,3 +38,10 @@ def set_generic_names_map(self, source_mappings: list[SourceMapping], default_ma
3738
class PredefinedField:
3839
def __init__(self, name: str):
3940
self.name = name
41+
42+
43+
class BaseFieldsGetter(ABC):
44+
@property
45+
@abstractmethod
46+
def fields(self) -> list[Field]:
47+
raise NotImplementedError("Abstract method")

uncoder-core/app/translator/core/models/query_tokens/field_field.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from app.translator.core.models.query_tokens.field import Alias, Field
1+
from app.translator.core.models.query_tokens.field import Alias, BaseFieldsGetter, Field
22
from app.translator.core.models.query_tokens.identifier import Identifier
33

44

5-
class FieldField:
5+
class FieldField(BaseFieldsGetter):
66
def __init__(
77
self,
88
source_name_left: str,
@@ -16,3 +16,13 @@ def __init__(
1616
self.operator = operator
1717
self.field_right = Field(source_name=source_name_right) if not is_alias_right else None
1818
self.alias_right = Alias(name=source_name_right) if is_alias_right else None
19+
20+
@property
21+
def fields(self) -> list[Field]:
22+
fields = []
23+
if self.field_left:
24+
fields.append(self.field_left)
25+
if self.field_right:
26+
fields.append(self.field_right)
27+
28+
return fields

uncoder-core/app/translator/core/models/query_tokens/field_value.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from typing import Union
22

33
from app.translator.core.custom_types.tokens import STR_SEARCH_OPERATORS
4-
from app.translator.core.models.query_tokens.field import Alias, Field, PredefinedField
4+
from app.translator.core.models.query_tokens.field import Alias, BaseFieldsGetter, Field, PredefinedField
55
from app.translator.core.models.query_tokens.identifier import Identifier
66
from app.translator.core.models.query_tokens.value import Value
77
from app.translator.core.str_value_manager import StrValue
88

99

10-
class FieldValue(Value):
10+
class FieldValue(BaseFieldsGetter, Value):
1111
def __init__(
1212
self,
1313
source_name: str,
@@ -33,3 +33,7 @@ def __repr__(self):
3333
return f"{self.predefined_field.name} {self.operator.token_type} {self.values}"
3434

3535
return f"{self.field.source_name} {self.operator.token_type} {self.values}"
36+
37+
@property
38+
def fields(self) -> list[Field]:
39+
return [self.field] if self.field else []

uncoder-core/app/translator/core/models/query_tokens/function_value.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22

33
from app.translator.core.custom_types.tokens import STR_SEARCH_OPERATORS
44
from app.translator.core.models.functions.base import Function
5+
from app.translator.core.models.query_tokens.field import BaseFieldsGetter, Field
56
from app.translator.core.models.query_tokens.identifier import Identifier
67
from app.translator.core.models.query_tokens.value import Value
78
from app.translator.core.str_value_manager import StrValue
89

910

10-
class FunctionValue(Value):
11+
class FunctionValue(BaseFieldsGetter, Value):
1112
def __init__(self, function: Function, operator: Identifier, value: Union[int, str, StrValue, list, tuple]):
1213
super().__init__(value, cast_to_int=operator.token_type not in STR_SEARCH_OPERATORS)
1314
self.function = function
1415
self.operator = operator
16+
17+
@property
18+
def fields(self) -> list[Field]:
19+
return self.function.fields

uncoder-core/app/translator/core/parser.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,17 @@ def get_query_tokens(self, query: str) -> list[QUERY_TOKEN_TYPE]:
6262
raise TokenizerGeneralException("Can't translate empty query. Please provide more details")
6363
return self.tokenizer.tokenize(query=query)
6464

65+
@staticmethod
6566
def get_field_tokens(
66-
self, query_tokens: list[QUERY_TOKEN_TYPE], functions: Optional[list[Function]] = None
67+
query_tokens: list[QUERY_TOKEN_TYPE], functions: Optional[list[Function]] = None
6768
) -> list[Field]:
6869
field_tokens = []
6970
for token in query_tokens:
70-
if isinstance(token, FieldValue):
71-
field_tokens.append(token.field)
72-
elif isinstance(token, FieldField):
73-
if token.field_left:
74-
field_tokens.append(token.field_left)
75-
if token.field_right:
76-
field_tokens.append(token.field_right)
77-
elif isinstance(token, FunctionValue):
78-
field_tokens.extend(self.tokenizer.get_field_tokens_from_func_args([token.function]))
71+
if isinstance(token, (FieldField, FieldValue, FunctionValue)):
72+
field_tokens.extend(token.fields)
7973

8074
if functions:
81-
field_tokens.extend(self.tokenizer.get_field_tokens_from_func_args(functions))
75+
field_tokens.extend([field for func in functions for field in func.fields])
8276

8377
return field_tokens
8478

uncoder-core/app/translator/core/tokenizer.py

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,6 @@
3131
)
3232
from app.translator.core.functions import PlatformFunctions
3333
from app.translator.core.mapping import SourceMapping
34-
from app.translator.core.models.functions.base import Function
35-
from app.translator.core.models.functions.eval import EvalArg
36-
from app.translator.core.models.functions.group_by import GroupByFunction
37-
from app.translator.core.models.functions.join import JoinFunction
38-
from app.translator.core.models.functions.rename import RenameArg
39-
from app.translator.core.models.functions.sort import SortArg
40-
from app.translator.core.models.functions.union import UnionFunction
4134
from app.translator.core.models.query_tokens.field import Field
4235
from app.translator.core.models.query_tokens.field_field import FieldField
4336
from app.translator.core.models.query_tokens.field_value import FieldValue
@@ -356,43 +349,6 @@ def filter_tokens(
356349
) -> list[QUERY_TOKEN_TYPE]:
357350
return [token for token in tokens if isinstance(token, token_type)]
358351

359-
def get_field_tokens_from_func_args( # noqa: PLR0912
360-
self, args: list[Union[Field, FieldValue, Keyword, Identifier, Function, SortArg]]
361-
) -> list[Field]:
362-
result = []
363-
for arg in args:
364-
if isinstance(arg, Field):
365-
result.append(arg)
366-
elif isinstance(arg, FieldField):
367-
if arg.field_left:
368-
result.append(arg.field_left)
369-
if arg.field_right:
370-
result.append(arg.field_right)
371-
elif isinstance(arg, FieldValue):
372-
if arg.field:
373-
result.append(arg.field)
374-
elif isinstance(arg, FunctionValue):
375-
result.extend(self.get_field_tokens_from_func_args(args=[arg.function]))
376-
elif isinstance(arg, GroupByFunction):
377-
result.extend(self.get_field_tokens_from_func_args(args=arg.args))
378-
result.extend(self.get_field_tokens_from_func_args(args=arg.by_clauses))
379-
result.extend(self.get_field_tokens_from_func_args(args=[arg.filter_]))
380-
elif isinstance(arg, JoinFunction):
381-
result.extend(self.get_field_tokens_from_func_args(args=arg.condition))
382-
elif isinstance(arg, UnionFunction):
383-
continue
384-
elif isinstance(arg, Function):
385-
result.extend(self.get_field_tokens_from_func_args(args=arg.args))
386-
elif isinstance(arg, SortArg) and isinstance(arg.field, Field):
387-
result.append(arg.field)
388-
elif isinstance(arg, RenameArg):
389-
result.append(arg.field_)
390-
elif isinstance(arg, EvalArg):
391-
if isinstance(arg.field_, Field):
392-
result.append(arg.field_)
393-
result.extend(self.get_field_tokens_from_func_args(args=arg.expression))
394-
return result
395-
396352
@staticmethod
397353
def set_field_tokens_generic_names_map(
398354
tokens: list[Field], source_mappings: list[SourceMapping], default_mapping: SourceMapping

0 commit comments

Comments
 (0)