pytrilogy 0.0.3.72__tar.gz → 0.0.3.74__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pytrilogy might be problematic. Click here for more details.

Files changed (150) hide show
  1. {pytrilogy-0.0.3.72/pytrilogy.egg-info → pytrilogy-0.0.3.74}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_functions.py +3 -3
  4. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/__init__.py +1 -1
  5. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/authoring/__init__.py +2 -2
  6. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/constants.py +1 -1
  7. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/enums.py +8 -0
  8. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/functions.py +56 -9
  9. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/models/author.py +20 -11
  10. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/models/build.py +14 -5
  11. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/models/core.py +13 -11
  12. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/models/execute.py +0 -1
  13. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/window_node.py +2 -0
  14. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/utility.py +20 -2
  15. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/base.py +20 -6
  16. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/bigquery.py +2 -1
  17. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/common.py +1 -0
  18. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/duckdb.py +18 -0
  19. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/postgres.py +2 -1
  20. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/presto.py +2 -1
  21. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/snowflake.py +2 -1
  22. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/sql_server.py +2 -1
  23. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/parsing/parse_engine.py +56 -7
  24. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/parsing/render.py +2 -2
  25. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/parsing/trilogy.lark +18 -3
  26. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/LICENSE.md +0 -0
  27. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/README.md +0 -0
  28. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/pyproject.toml +0 -0
  29. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/pytrilogy.egg-info/SOURCES.txt +0 -0
  30. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/pytrilogy.egg-info/dependency_links.txt +0 -0
  31. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/pytrilogy.egg-info/entry_points.txt +0 -0
  32. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/pytrilogy.egg-info/requires.txt +0 -0
  33. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/pytrilogy.egg-info/top_level.txt +0 -0
  34. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/setup.cfg +0 -0
  35. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/setup.py +0 -0
  36. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_datatypes.py +0 -0
  37. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_declarations.py +0 -0
  38. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_derived_concepts.py +0 -0
  39. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_discovery_nodes.py +0 -0
  40. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_enums.py +0 -0
  41. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_environment.py +0 -0
  42. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_execute_models.py +0 -0
  43. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_executor.py +0 -0
  44. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_failure.py +0 -0
  45. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_imports.py +0 -0
  46. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_metadata.py +0 -0
  47. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_models.py +0 -0
  48. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_multi_join_assignments.py +0 -0
  49. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_parse_engine.py +0 -0
  50. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_parsing.py +0 -0
  51. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_parsing_failures.py +0 -0
  52. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_partial_handling.py +0 -0
  53. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_query_processing.py +0 -0
  54. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_query_render.py +0 -0
  55. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_select.py +0 -0
  56. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_show.py +0 -0
  57. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_statements.py +0 -0
  58. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_typing.py +0 -0
  59. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_undefined_concept.py +0 -0
  60. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_user_functions.py +0 -0
  61. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/tests/test_where_clause.py +0 -0
  62. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/compiler.py +0 -0
  63. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/__init__.py +0 -0
  64. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/constants.py +0 -0
  65. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/env_processor.py +0 -0
  66. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/environment_helpers.py +0 -0
  67. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/ergonomics.py +0 -0
  68. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/exceptions.py +0 -0
  69. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/graph_models.py +0 -0
  70. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/internal.py +0 -0
  71. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/models/__init__.py +0 -0
  72. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/models/build_environment.py +0 -0
  73. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/models/datasource.py +0 -0
  74. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/models/environment.py +0 -0
  75. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/optimization.py +0 -0
  76. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/optimizations/__init__.py +0 -0
  77. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/optimizations/base_optimization.py +0 -0
  78. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/optimizations/inline_datasource.py +0 -0
  79. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  80. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/__init__.py +0 -0
  81. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/concept_strategies_v3.py +0 -0
  82. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/discovery_loop.py +0 -0
  83. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/discovery_node_factory.py +0 -0
  84. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/discovery_utility.py +0 -0
  85. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/discovery_validation.py +0 -0
  86. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/graph_utils.py +0 -0
  87. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/__init__.py +0 -0
  88. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  89. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/common.py +0 -0
  90. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  91. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/group_node.py +0 -0
  92. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  93. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  94. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  95. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/recursive_node.py +0 -0
  96. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  97. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
  98. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
  99. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
  100. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/select_node.py +0 -0
  101. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
  102. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/union_node.py +0 -0
  103. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  104. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/nodes/__init__.py +0 -0
  105. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/nodes/base_node.py +0 -0
  106. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/nodes/filter_node.py +0 -0
  107. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/nodes/group_node.py +0 -0
  108. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/nodes/merge_node.py +0 -0
  109. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/nodes/recursive_node.py +0 -0
  110. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  111. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/nodes/union_node.py +0 -0
  112. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  113. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/processing/nodes/window_node.py +0 -0
  114. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/query_processor.py +0 -0
  115. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/statements/__init__.py +0 -0
  116. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/statements/author.py +0 -0
  117. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/statements/build.py +0 -0
  118. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/statements/common.py +0 -0
  119. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/statements/execute.py +0 -0
  120. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/core/utility.py +0 -0
  121. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/__init__.py +0 -0
  122. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/config.py +0 -0
  123. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/dataframe.py +0 -0
  124. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/dialect/enums.py +0 -0
  125. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/engine.py +0 -0
  126. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/executor.py +0 -0
  127. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/hooks/__init__.py +0 -0
  128. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/hooks/base_hook.py +0 -0
  129. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/hooks/graph_hook.py +0 -0
  130. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/hooks/query_debugger.py +0 -0
  131. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/metadata/__init__.py +0 -0
  132. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/parser.py +0 -0
  133. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/parsing/__init__.py +0 -0
  134. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/parsing/common.py +0 -0
  135. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/parsing/config.py +0 -0
  136. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/parsing/exceptions.py +0 -0
  137. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/parsing/helpers.py +0 -0
  138. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/py.typed +0 -0
  139. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/render.py +0 -0
  140. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/scripts/__init__.py +0 -0
  141. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/scripts/trilogy.py +0 -0
  142. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/std/__init__.py +0 -0
  143. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/std/date.preql +0 -0
  144. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/std/display.preql +0 -0
  145. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/std/geography.preql +0 -0
  146. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/std/money.preql +0 -0
  147. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/std/net.preql +0 -0
  148. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/std/ranking.preql +0 -0
  149. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/std/report.preql +0 -0
  150. {pytrilogy-0.0.3.72 → pytrilogy-0.0.3.74}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytrilogy
3
- Version: 0.0.3.72
3
+ Version: 0.0.3.74
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytrilogy
3
- Version: 0.0.3.72
3
+ Version: 0.0.3.74
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -8,7 +8,7 @@ from trilogy import Dialects
8
8
  from trilogy.constants import logger
9
9
  from trilogy.core.enums import Derivation, Purpose
10
10
  from trilogy.core.exceptions import InvalidSyntaxException
11
- from trilogy.core.models.core import DataType, ListType
11
+ from trilogy.core.models.core import ArrayType, DataType
12
12
  from trilogy.core.models.environment import Environment
13
13
  from trilogy.core.query_processor import process_query
14
14
  from trilogy.core.statements.author import SelectStatement
@@ -31,7 +31,7 @@ TEST_DIALECTS = [
31
31
 
32
32
 
33
33
  def test_typing():
34
- x = ListType(type=DataType.INTEGER)
34
+ x = ArrayType(type=DataType.INTEGER)
35
35
 
36
36
  assert x in set([x])
37
37
 
@@ -393,7 +393,7 @@ def test_unnest(test_environment):
393
393
  x
394
394
  ;"""
395
395
  env, parsed = parse(declarations, environment=test_environment)
396
- assert env.concepts["int_list"].datatype == ListType(type=DataType.INTEGER)
396
+ assert env.concepts["int_list"].datatype == ArrayType(type=DataType.INTEGER)
397
397
  assert env.concepts["x"].datatype == DataType.INTEGER
398
398
 
399
399
 
@@ -4,6 +4,6 @@ from trilogy.dialect.enums import Dialects
4
4
  from trilogy.executor import Executor
5
5
  from trilogy.parser import parse
6
6
 
7
- __version__ = "0.0.3.72"
7
+ __version__ = "0.0.3.74"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -37,8 +37,8 @@ from trilogy.core.models.author import (
37
37
  WindowType,
38
38
  )
39
39
  from trilogy.core.models.core import (
40
+ ArrayType,
40
41
  DataType,
41
- ListType,
42
42
  ListWrapper,
43
43
  MapType,
44
44
  StructType,
@@ -77,7 +77,7 @@ __all__ = [
77
77
  "WindowItemOver",
78
78
  "DataType",
79
79
  "StructType",
80
- "ListType",
80
+ "ArrayType",
81
81
  "Grain",
82
82
  "RowsetDerivationStatement",
83
83
  "MapType",
@@ -37,7 +37,7 @@ class Comments:
37
37
  show: bool = False
38
38
  basic: bool = True
39
39
  joins: bool = True
40
- nullable: bool = False
40
+ nullable: bool = True
41
41
  partial: bool = True
42
42
 
43
43
 
@@ -149,6 +149,12 @@ class FunctionType(Enum):
149
149
  DATE_LITERAL = "date_literal"
150
150
  DATETIME_LITERAL = "datetime_literal"
151
151
 
152
+ # ARRAY
153
+ ARRAY_DISTINCT = "array_distinct"
154
+ ARRAY_SUM = "array_sum"
155
+ ARRAY_SORT = "array_sort"
156
+ ARRAY_TRANSFORM = "array_transform"
157
+
152
158
  # TEXT AND MAYBE MORE
153
159
  SPLIT = "split"
154
160
  LENGTH = "len"
@@ -177,6 +183,7 @@ class FunctionType(Enum):
177
183
  MAX = "max"
178
184
  MIN = "min"
179
185
  AVG = "avg"
186
+ ARRAY_AGG = "array_agg"
180
187
 
181
188
  # String
182
189
  LIKE = "like"
@@ -228,6 +235,7 @@ class FunctionClass(Enum):
228
235
  FunctionType.MIN,
229
236
  FunctionType.SUM,
230
237
  FunctionType.AVG,
238
+ FunctionType.ARRAY_AGG,
231
239
  FunctionType.COUNT,
232
240
  FunctionType.COUNT_DISTINCT,
233
241
  ]
@@ -25,8 +25,8 @@ from trilogy.core.models.author import (
25
25
  )
26
26
  from trilogy.core.models.core import (
27
27
  CONCRETE_TYPES,
28
+ ArrayType,
28
29
  DataType,
29
- ListType,
30
30
  MapType,
31
31
  NumericType,
32
32
  StructType,
@@ -45,14 +45,14 @@ class FunctionConfig:
45
45
  valid_inputs: set[DataType] | list[set[DataType]] | None = None
46
46
  output_purpose: Purpose | None = None
47
47
  output_type: (
48
- DataType | ListType | MapType | StructType | NumericType | TraitDataType | None
48
+ DataType | ArrayType | MapType | StructType | NumericType | TraitDataType | None
49
49
  ) = None
50
50
  output_type_function: Optional[Callable] = None
51
51
 
52
52
 
53
53
  def get_unnest_output_type(args: list[Any]) -> CONCRETE_TYPES:
54
54
  output = arg_to_datatype(args[0])
55
- if isinstance(output, (ListType, MapType)):
55
+ if isinstance(output, (ArrayType, MapType)):
56
56
  output = output.value_data_type
57
57
  else:
58
58
  output = DataType.STRING
@@ -69,12 +69,16 @@ def get_coalesce_output_type(args: list[Any]) -> CONCRETE_TYPES:
69
69
  return processed[0]
70
70
 
71
71
 
72
+ def get_transform_output_type(args: list[Any]) -> CONCRETE_TYPES:
73
+ return arg_to_datatype(args[2])
74
+
75
+
72
76
  def get_index_output_type(
73
77
  args: list[Any],
74
78
  ) -> CONCRETE_TYPES:
75
79
  arg = args[0]
76
80
  datatype = arg_to_datatype(arg)
77
- if isinstance(datatype, ListType):
81
+ if isinstance(datatype, ArrayType):
78
82
  return datatype.value_data_type
79
83
  elif isinstance(datatype, MapType):
80
84
  return datatype.value_data_type
@@ -184,7 +188,6 @@ FUNCTION_REGISTRY: dict[FunctionType, FunctionConfig] = {
184
188
  FunctionType.UNNEST: FunctionConfig(
185
189
  valid_inputs={
186
190
  DataType.ARRAY,
187
- DataType.LIST,
188
191
  },
189
192
  output_purpose=Purpose.KEY,
190
193
  output_type_function=get_unnest_output_type,
@@ -235,13 +238,12 @@ FUNCTION_REGISTRY: dict[FunctionType, FunctionConfig] = {
235
238
  FunctionType.SPLIT: FunctionConfig(
236
239
  valid_inputs={DataType.STRING},
237
240
  output_purpose=Purpose.PROPERTY,
238
- output_type=ListType(type=DataType.STRING),
241
+ output_type=ArrayType(type=DataType.STRING),
239
242
  arg_count=2,
240
243
  ),
241
244
  FunctionType.INDEX_ACCESS: FunctionConfig(
242
245
  valid_inputs=[
243
246
  {
244
- DataType.LIST,
245
247
  DataType.ARRAY,
246
248
  },
247
249
  {
@@ -252,6 +254,43 @@ FUNCTION_REGISTRY: dict[FunctionType, FunctionConfig] = {
252
254
  output_type_function=get_index_output_type,
253
255
  arg_count=2,
254
256
  ),
257
+ FunctionType.ARRAY_DISTINCT: FunctionConfig(
258
+ valid_inputs={
259
+ DataType.ARRAY,
260
+ },
261
+ output_purpose=Purpose.PROPERTY,
262
+ output_type_function=lambda args: get_output_type_at_index(args, 0),
263
+ arg_count=1,
264
+ ),
265
+ FunctionType.ARRAY_SORT: FunctionConfig(
266
+ valid_inputs=[
267
+ {DataType.ARRAY},
268
+ {DataType.STRING},
269
+ ],
270
+ output_purpose=Purpose.PROPERTY,
271
+ output_type_function=lambda args: get_output_type_at_index(args, 0),
272
+ arg_count=2,
273
+ ),
274
+ FunctionType.ARRAY_TRANSFORM: FunctionConfig(
275
+ valid_inputs=[
276
+ {
277
+ DataType.ARRAY,
278
+ },
279
+ {*DataType},
280
+ {*DataType},
281
+ ],
282
+ output_purpose=Purpose.PROPERTY,
283
+ output_type_function=get_transform_output_type,
284
+ arg_count=3,
285
+ ),
286
+ FunctionType.ARRAY_SUM: FunctionConfig(
287
+ valid_inputs={
288
+ DataType.ARRAY,
289
+ },
290
+ output_purpose=Purpose.PROPERTY,
291
+ output_type_function=get_index_output_type,
292
+ arg_count=1,
293
+ ),
255
294
  FunctionType.MAP_ACCESS: FunctionConfig(
256
295
  valid_inputs=[
257
296
  {
@@ -722,7 +761,7 @@ FUNCTION_REGISTRY: dict[FunctionType, FunctionConfig] = {
722
761
  FunctionType.ARRAY: FunctionConfig(
723
762
  output_purpose=Purpose.PROPERTY,
724
763
  arg_count=InfiniteFunctionArgs,
725
- output_type=ListType(type=DataType.STRING),
764
+ output_type=ArrayType(type=DataType.STRING),
726
765
  ),
727
766
  FunctionType.LENGTH: FunctionConfig(
728
767
  valid_inputs={DataType.STRING, DataType.ARRAY, DataType.MAP},
@@ -740,6 +779,14 @@ FUNCTION_REGISTRY: dict[FunctionType, FunctionConfig] = {
740
779
  output_purpose=Purpose.METRIC,
741
780
  arg_count=1,
742
781
  ),
782
+ FunctionType.ARRAY_AGG: FunctionConfig(
783
+ valid_inputs={*DataType},
784
+ output_purpose=Purpose.METRIC,
785
+ output_type_function=lambda args: ArrayType(
786
+ type=merge_datatypes([arg_to_datatype(x) for x in args])
787
+ ),
788
+ arg_count=1,
789
+ ),
743
790
  FunctionType.AVG: FunctionConfig(
744
791
  valid_inputs={
745
792
  DataType.INTEGER,
@@ -837,7 +884,7 @@ def create_function_derived_concept(
837
884
  arguments: list[Concept],
838
885
  environment: Environment,
839
886
  output_type: Optional[
840
- DataType | ListType | StructType | MapType | NumericType | TraitDataType
887
+ DataType | ArrayType | StructType | MapType | NumericType | TraitDataType
841
888
  ] = None,
842
889
  output_purpose: Optional[Purpose] = None,
843
890
  ) -> Concept:
@@ -48,9 +48,9 @@ from trilogy.core.enums import (
48
48
  )
49
49
  from trilogy.core.models.core import (
50
50
  Addressable,
51
+ ArrayType,
51
52
  DataType,
52
53
  DataTyped,
53
- ListType,
54
54
  ListWrapper,
55
55
  MapType,
56
56
  MapWrapper,
@@ -104,7 +104,7 @@ class HasUUID(ABC):
104
104
  class ConceptRef(Addressable, Namespaced, DataTyped, Mergeable, BaseModel):
105
105
  address: str
106
106
  datatype: (
107
- DataType | TraitDataType | ListType | StructType | MapType | NumericType
107
+ DataType | TraitDataType | ArrayType | StructType | MapType | NumericType
108
108
  ) = DataType.UNKNOWN
109
109
  metadata: Optional["Metadata"] = None
110
110
 
@@ -646,7 +646,7 @@ class Comparison(ConceptArgs, Mergeable, DataTyped, Namespaced, BaseModel):
646
646
  )
647
647
  elif self.operator in (ComparisonOperator.IN, ComparisonOperator.NOT_IN):
648
648
  right_type = arg_to_datatype(self.right)
649
- if isinstance(right_type, ListType) and not is_compatible_datatype(
649
+ if isinstance(right_type, ArrayType) and not is_compatible_datatype(
650
650
  arg_to_datatype(self.left), right_type.value_data_type
651
651
  ):
652
652
  raise SyntaxError(
@@ -802,7 +802,7 @@ class Concept(Addressable, DataTyped, ConceptArgs, Mergeable, Namespaced, BaseMo
802
802
  extra="forbid",
803
803
  )
804
804
  name: str
805
- datatype: DataType | TraitDataType | ListType | StructType | MapType | NumericType
805
+ datatype: DataType | TraitDataType | ArrayType | StructType | MapType | NumericType
806
806
  purpose: Purpose
807
807
  derivation: Derivation = Derivation.ROOT
808
808
  granularity: Granularity = Granularity.MULTI_ROW
@@ -1277,7 +1277,7 @@ class UndefinedConceptFull(Concept, Mergeable, Namespaced):
1277
1277
  name: str
1278
1278
  line_no: int | None = None
1279
1279
  datatype: (
1280
- DataType | TraitDataType | ListType | StructType | MapType | NumericType
1280
+ DataType | TraitDataType | ArrayType | StructType | MapType | NumericType
1281
1281
  ) = DataType.UNKNOWN
1282
1282
  purpose: Purpose = Purpose.UNKNOWN
1283
1283
 
@@ -1437,10 +1437,10 @@ class WindowItem(DataTyped, ConceptArgs, Mergeable, Namespaced, BaseModel):
1437
1437
 
1438
1438
 
1439
1439
  def get_basic_type(
1440
- type: DataType | ListType | StructType | MapType | NumericType | TraitDataType,
1440
+ type: DataType | ArrayType | StructType | MapType | NumericType | TraitDataType,
1441
1441
  ) -> DataType:
1442
- if isinstance(type, ListType):
1443
- return DataType.LIST
1442
+ if isinstance(type, ArrayType):
1443
+ return DataType.ARRAY
1444
1444
  if isinstance(type, StructType):
1445
1445
  return DataType.STRUCT
1446
1446
  if isinstance(type, MapType):
@@ -1609,7 +1609,7 @@ class Function(DataTyped, ConceptArgs, Mergeable, Namespaced, BaseModel):
1609
1609
  operator: FunctionType
1610
1610
  arg_count: int = Field(default=1)
1611
1611
  output_datatype: (
1612
- DataType | ListType | StructType | MapType | NumericType | TraitDataType
1612
+ DataType | ArrayType | StructType | MapType | NumericType | TraitDataType
1613
1613
  )
1614
1614
  output_purpose: Purpose
1615
1615
  valid_inputs: Optional[
@@ -2358,9 +2358,10 @@ class Comment(BaseModel):
2358
2358
  text: str
2359
2359
 
2360
2360
 
2361
- class ArgBinding(Namespaced, BaseModel):
2361
+ class ArgBinding(Namespaced, DataTyped, BaseModel):
2362
2362
  name: str
2363
2363
  default: Expr | None = None
2364
+ datatype: DataType = DataType.UNKNOWN
2364
2365
 
2365
2366
  def with_namespace(self, namespace):
2366
2367
  return ArgBinding(
@@ -2372,6 +2373,12 @@ class ArgBinding(Namespaced, BaseModel):
2372
2373
  ),
2373
2374
  )
2374
2375
 
2376
+ @property
2377
+ def output_datatype(self):
2378
+ if self.default is not None:
2379
+ return arg_to_datatype(self.default)
2380
+ return self.datatype
2381
+
2375
2382
 
2376
2383
  class CustomType(BaseModel):
2377
2384
  name: str
@@ -2426,7 +2433,7 @@ FuncArgs = (
2426
2433
  | MapWrapper[Any, Any]
2427
2434
  | TraitDataType
2428
2435
  | DataType
2429
- | ListType
2436
+ | ArrayType
2430
2437
  | MapType
2431
2438
  | NumericType
2432
2439
  | ListWrapper[Any]
@@ -2434,4 +2441,6 @@ FuncArgs = (
2434
2441
  | Comparison
2435
2442
  | Conditional
2436
2443
  | MagicConstants
2444
+ | ArgBinding
2445
+ | Ordering
2437
2446
  )
@@ -45,6 +45,7 @@ from trilogy.core.models.author import (
45
45
  AggregateWrapper,
46
46
  AlignClause,
47
47
  AlignItem,
48
+ ArgBinding,
48
49
  CaseElse,
49
50
  CaseWhen,
50
51
  Comparison,
@@ -72,9 +73,9 @@ from trilogy.core.models.author import (
72
73
  )
73
74
  from trilogy.core.models.core import (
74
75
  Addressable,
76
+ ArrayType,
75
77
  DataType,
76
78
  DataTyped,
77
- ListType,
78
79
  ListWrapper,
79
80
  MapType,
80
81
  MapWrapper,
@@ -791,7 +792,7 @@ class BuildSubselectComparison(BuildComparison):
791
792
  class BuildConcept(Addressable, BuildConceptArgs, DataTyped, BaseModel):
792
793
  model_config = ConfigDict(extra="forbid")
793
794
  name: str
794
- datatype: DataType | ListType | StructType | MapType | NumericType
795
+ datatype: DataType | ArrayType | StructType | MapType | NumericType
795
796
  purpose: Purpose
796
797
  build_is_aggregate: bool
797
798
  derivation: Derivation = Derivation.ROOT
@@ -1083,7 +1084,7 @@ class BuildFunction(DataTyped, BuildConceptArgs, BaseModel):
1083
1084
  operator: FunctionType
1084
1085
  arg_count: int = Field(default=1)
1085
1086
  output_datatype: (
1086
- DataType | ListType | StructType | MapType | NumericType | TraitDataType
1087
+ DataType | ArrayType | StructType | MapType | NumericType | TraitDataType
1087
1088
  )
1088
1089
  output_purpose: Purpose
1089
1090
  valid_inputs: Optional[
@@ -1102,7 +1103,7 @@ class BuildFunction(DataTyped, BuildConceptArgs, BaseModel):
1102
1103
  MapWrapper[Any, Any],
1103
1104
  TraitDataType,
1104
1105
  DataType,
1105
- ListType,
1106
+ ArrayType,
1106
1107
  MapType,
1107
1108
  NumericType,
1108
1109
  DatePart,
@@ -2075,7 +2076,7 @@ class Factory:
2075
2076
  return base
2076
2077
 
2077
2078
  @build.register
2078
- def _(self, base: ListType):
2079
+ def _(self, base: ArrayType):
2079
2080
  return base
2080
2081
 
2081
2082
  @build.register
@@ -2086,6 +2087,14 @@ class Factory:
2086
2087
  def _(self, base: MapType):
2087
2088
  return base
2088
2089
 
2090
+ @build.register
2091
+ def _(self, base: ArgBinding):
2092
+ return base
2093
+
2094
+ @build.register
2095
+ def _(self, base: Ordering):
2096
+ return base
2097
+
2089
2098
  @build.register
2090
2099
  def _(self, base: Datasource):
2091
2100
  local_cache: dict[str, BuildConcept] = {}
@@ -27,6 +27,7 @@ from pydantic_core import core_schema
27
27
  from trilogy.constants import (
28
28
  MagicConstants,
29
29
  )
30
+ from trilogy.core.enums import Ordering
30
31
 
31
32
 
32
33
  class DataTyped(ABC):
@@ -53,7 +54,7 @@ class Addressable(ABC):
53
54
  TYPEDEF_TYPES = Union[
54
55
  "DataType",
55
56
  "MapType",
56
- "ListType",
57
+ "ArrayType",
57
58
  "NumericType",
58
59
  "StructType",
59
60
  "DataTyped",
@@ -63,7 +64,7 @@ TYPEDEF_TYPES = Union[
63
64
  CONCRETE_TYPES = Union[
64
65
  "DataType",
65
66
  "MapType",
66
- "ListType",
67
+ "ArrayType",
67
68
  "NumericType",
68
69
  "StructType",
69
70
  "TraitDataType",
@@ -79,7 +80,6 @@ class DataType(Enum):
79
80
  STRING = "string"
80
81
  BOOL = "bool"
81
82
  MAP = "map"
82
- LIST = "list"
83
83
  NUMBER = "number"
84
84
  FLOAT = "float"
85
85
  NUMERIC = "numeric"
@@ -105,7 +105,7 @@ class DataType(Enum):
105
105
 
106
106
 
107
107
  class TraitDataType(BaseModel):
108
- type: DataType | NumericType | StructType | ListType | MapType
108
+ type: DataType | NumericType | StructType | ArrayType | MapType
109
109
  traits: list[str]
110
110
 
111
111
  def __hash__(self):
@@ -146,7 +146,7 @@ class NumericType(BaseModel):
146
146
  return self.data_type.value
147
147
 
148
148
 
149
- class ListType(BaseModel):
149
+ class ArrayType(BaseModel):
150
150
  model_config = ConfigDict(frozen=True)
151
151
  type: TYPEDEF_TYPES
152
152
 
@@ -159,7 +159,7 @@ class ListType(BaseModel):
159
159
 
160
160
  @property
161
161
  def data_type(self):
162
- return DataType.LIST
162
+ return DataType.ARRAY
163
163
 
164
164
  @property
165
165
  def value(self):
@@ -340,9 +340,9 @@ def dict_to_map_wrapper(arg):
340
340
 
341
341
  def merge_datatypes(
342
342
  inputs: list[
343
- DataType | ListType | StructType | MapType | NumericType | TraitDataType
343
+ DataType | ArrayType | StructType | MapType | NumericType | TraitDataType
344
344
  ],
345
- ) -> DataType | ListType | StructType | MapType | NumericType | TraitDataType:
345
+ ) -> DataType | ArrayType | StructType | MapType | NumericType | TraitDataType:
346
346
  """This is a temporary hack for doing between
347
347
  allowable datatype transformation matrix"""
348
348
  if len(inputs) == 1:
@@ -393,6 +393,8 @@ def arg_to_datatype(arg) -> CONCRETE_TYPES:
393
393
  raise ValueError(f"Cannot parse arg datatype for arg of type {arg}")
394
394
  elif isinstance(arg, bool):
395
395
  return DataType.BOOL
396
+ elif isinstance(arg, Ordering):
397
+ return DataType.STRING # TODO: revisit
396
398
  elif isinstance(arg, int):
397
399
  return DataType.INTEGER
398
400
  elif isinstance(arg, str):
@@ -404,14 +406,14 @@ def arg_to_datatype(arg) -> CONCRETE_TYPES:
404
406
  elif isinstance(arg, TraitDataType):
405
407
  return arg
406
408
  elif isinstance(arg, ListWrapper):
407
- return ListType(type=arg.type)
409
+ return ArrayType(type=arg.type)
408
410
  elif isinstance(arg, DataTyped):
409
411
  return arg.output_datatype
410
412
  elif isinstance(arg, TupleWrapper):
411
- return ListType(type=arg.type)
413
+ return ArrayType(type=arg.type)
412
414
  elif isinstance(arg, list):
413
415
  wrapper = list_to_wrapper(arg)
414
- return ListType(type=wrapper.type)
416
+ return ArrayType(type=wrapper.type)
415
417
  elif isinstance(arg, MapWrapper):
416
418
  return MapType(key_type=arg.key_type, value_type=arg.value_type)
417
419
  elif isinstance(arg, datetime):
@@ -501,7 +501,6 @@ class BaseJoin(BaseModel):
501
501
  f"Cannot join a dataself to itself, joining {self.left_datasource} and"
502
502
  f" {self.right_datasource}"
503
503
  )
504
-
505
504
  # Early returns maintained as in original code
506
505
  if self.concept_pairs or self.concepts == []:
507
506
  return self
@@ -69,6 +69,8 @@ def gen_window_node(
69
69
  # append in keys to get the right grain
70
70
  if concept.keys:
71
71
  for item in concept.keys:
72
+ if item in targets:
73
+ continue
72
74
  logger.info(
73
75
  f"{padding(depth)}{LOGGER_PREFIX} appending search for key {item}"
74
76
  )
@@ -13,6 +13,7 @@ from trilogy.core.enums import (
13
13
  FunctionClass,
14
14
  Granularity,
15
15
  JoinType,
16
+ Modifier,
16
17
  Purpose,
17
18
  )
18
19
  from trilogy.core.models.build import (
@@ -32,8 +33,8 @@ from trilogy.core.models.build import (
32
33
  )
33
34
  from trilogy.core.models.build_environment import BuildEnvironment
34
35
  from trilogy.core.models.core import (
36
+ ArrayType,
35
37
  DataType,
36
- ListType,
37
38
  ListWrapper,
38
39
  MapType,
39
40
  MapWrapper,
@@ -355,6 +356,20 @@ def reduce_concept_pairs(input: list[ConceptPair]) -> list[ConceptPair]:
355
356
  return final
356
357
 
357
358
 
359
+ def get_modifiers(
360
+ concept: str,
361
+ join: JoinOrderOutput,
362
+ ds_node_map: dict[str, QueryDatasource | BuildDatasource],
363
+ ):
364
+ base = []
365
+
366
+ if join.right and concept in ds_node_map[join.right].nullable_concepts:
367
+ base.append(Modifier.NULLABLE)
368
+ if join.left and concept in ds_node_map[join.left].nullable_concepts:
369
+ base.append(Modifier.NULLABLE)
370
+ return list(set(base))
371
+
372
+
358
373
  def get_node_joins(
359
374
  datasources: List[QueryDatasource | BuildDatasource],
360
375
  environment: BuildEnvironment,
@@ -400,6 +415,9 @@ def get_node_joins(
400
415
  concept_map[concept], ds_node_map[j.right]
401
416
  ),
402
417
  existing_datasource=ds_node_map[k],
418
+ modifiers=get_modifiers(
419
+ concept_map[concept].address, j, ds_node_map
420
+ ),
403
421
  )
404
422
  for k, v in j.keys.items()
405
423
  for concept in v
@@ -453,7 +471,7 @@ def is_scalar_condition(
453
471
  | TraitDataType
454
472
  | DataType
455
473
  | MapWrapper[Any, Any]
456
- | ListType
474
+ | ArrayType
457
475
  | MapType
458
476
  | NumericType
459
477
  | DatePart
@@ -15,10 +15,12 @@ from trilogy.core.enums import (
15
15
  ComparisonOperator,
16
16
  DatePart,
17
17
  FunctionType,
18
+ Ordering,
18
19
  UnnestMode,
19
20
  WindowType,
20
21
  )
21
22
  from trilogy.core.internal import DEFAULT_CONCEPTS
23
+ from trilogy.core.models.author import ArgBinding
22
24
  from trilogy.core.models.build import (
23
25
  BuildAggregateWrapper,
24
26
  BuildCaseElse,
@@ -37,8 +39,8 @@ from trilogy.core.models.build import (
37
39
  BuildWindowItem,
38
40
  )
39
41
  from trilogy.core.models.core import (
42
+ ArrayType,
40
43
  DataType,
41
- ListType,
42
44
  ListWrapper,
43
45
  MapType,
44
46
  MapWrapper,
@@ -142,11 +144,11 @@ DATATYPE_MAP: dict[DataType, str] = {
142
144
  DataType.MAP: "map",
143
145
  DataType.DATE: "date",
144
146
  DataType.DATETIME: "datetime",
145
- DataType.LIST: "list",
147
+ DataType.ARRAY: "list",
146
148
  }
147
149
 
148
150
  COMPLEX_DATATYPE_MAP = {
149
- DataType.LIST: lambda x: f"{x}[]",
151
+ DataType.ARRAY: lambda x: f"{x}[]",
150
152
  }
151
153
 
152
154
 
@@ -182,6 +184,13 @@ FUNCTION_MAP = {
182
184
  FunctionType.ARRAY: lambda x: f"[{', '.join(x)}]",
183
185
  FunctionType.DATE_LITERAL: lambda x: f"date '{x}'",
184
186
  FunctionType.DATETIME_LITERAL: lambda x: f"datetime '{x}'",
187
+ # ARRAY
188
+ FunctionType.ARRAY_SUM: lambda x: f"array_sum({x[0]})",
189
+ FunctionType.ARRAY_DISTINCT: lambda x: f"array_distinct({x[0]})",
190
+ FunctionType.ARRAY_SORT: lambda x: f"array_sort({x[0]})",
191
+ FunctionType.ARRAY_TRANSFORM: lambda args: (
192
+ f"array_transform({args[0]}, {args[1]} -> {args[2]})"
193
+ ),
185
194
  # math
186
195
  FunctionType.ADD: lambda x: " + ".join(x),
187
196
  FunctionType.ABS: lambda x: f"abs({x[0]})",
@@ -198,6 +207,7 @@ FUNCTION_MAP = {
198
207
  FunctionType.COUNT_DISTINCT: lambda x: f"count(distinct {x[0]})",
199
208
  FunctionType.COUNT: lambda x: f"count({x[0]})",
200
209
  FunctionType.SUM: lambda x: f"sum({x[0]})",
210
+ FunctionType.ARRAY_AGG: lambda x: f"array_agg({x[0]})",
201
211
  FunctionType.LENGTH: lambda x: f"length({x[0]})",
202
212
  FunctionType.AVG: lambda x: f"avg({x[0]})",
203
213
  FunctionType.MAX: lambda x: f"max({x[0]})",
@@ -569,7 +579,7 @@ class BaseDialect:
569
579
  MapType,
570
580
  NumericType,
571
581
  StructType,
572
- ListType,
582
+ ArrayType,
573
583
  ListWrapper[Any],
574
584
  TupleWrapper[Any],
575
585
  DatePart,
@@ -749,8 +759,12 @@ class BaseDialect:
749
759
  return self.FUNCTION_MAP[FunctionType.DATETIME_LITERAL](e)
750
760
  elif isinstance(e, TraitDataType):
751
761
  return self.render_expr(e.type, cte=cte, cte_map=cte_map)
752
- elif isinstance(e, ListType):
753
- return f"{self.COMPLEX_DATATYPE_MAP[DataType.LIST](self.render_expr(e.value_data_type, cte=cte, cte_map=cte_map))}"
762
+ elif isinstance(e, ArgBinding):
763
+ return e.name
764
+ elif isinstance(e, Ordering):
765
+ return str(e.value)
766
+ elif isinstance(e, ArrayType):
767
+ return f"{self.COMPLEX_DATATYPE_MAP[DataType.ARRAY](self.render_expr(e.value_data_type, cte=cte, cte_map=cte_map))}"
754
768
  elif isinstance(e, BuildParamaterizedConceptReference):
755
769
  if self.rendering.parameters:
756
770
  if e.concept.namespace == DEFAULT_NAMESPACE: