pytrilogy 0.3.148__cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

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.
Files changed (206) hide show
  1. LICENSE.md +19 -0
  2. _preql_import_resolver/__init__.py +5 -0
  3. _preql_import_resolver/_preql_import_resolver.cpython-312-aarch64-linux-gnu.so +0 -0
  4. pytrilogy-0.3.148.dist-info/METADATA +555 -0
  5. pytrilogy-0.3.148.dist-info/RECORD +206 -0
  6. pytrilogy-0.3.148.dist-info/WHEEL +5 -0
  7. pytrilogy-0.3.148.dist-info/entry_points.txt +2 -0
  8. pytrilogy-0.3.148.dist-info/licenses/LICENSE.md +19 -0
  9. trilogy/__init__.py +27 -0
  10. trilogy/ai/README.md +10 -0
  11. trilogy/ai/__init__.py +19 -0
  12. trilogy/ai/constants.py +92 -0
  13. trilogy/ai/conversation.py +107 -0
  14. trilogy/ai/enums.py +7 -0
  15. trilogy/ai/execute.py +50 -0
  16. trilogy/ai/models.py +34 -0
  17. trilogy/ai/prompts.py +100 -0
  18. trilogy/ai/providers/__init__.py +0 -0
  19. trilogy/ai/providers/anthropic.py +106 -0
  20. trilogy/ai/providers/base.py +24 -0
  21. trilogy/ai/providers/google.py +146 -0
  22. trilogy/ai/providers/openai.py +89 -0
  23. trilogy/ai/providers/utils.py +68 -0
  24. trilogy/authoring/README.md +3 -0
  25. trilogy/authoring/__init__.py +148 -0
  26. trilogy/constants.py +119 -0
  27. trilogy/core/README.md +52 -0
  28. trilogy/core/__init__.py +0 -0
  29. trilogy/core/constants.py +6 -0
  30. trilogy/core/enums.py +454 -0
  31. trilogy/core/env_processor.py +239 -0
  32. trilogy/core/environment_helpers.py +320 -0
  33. trilogy/core/ergonomics.py +193 -0
  34. trilogy/core/exceptions.py +123 -0
  35. trilogy/core/functions.py +1240 -0
  36. trilogy/core/graph_models.py +142 -0
  37. trilogy/core/internal.py +85 -0
  38. trilogy/core/models/__init__.py +0 -0
  39. trilogy/core/models/author.py +2662 -0
  40. trilogy/core/models/build.py +2603 -0
  41. trilogy/core/models/build_environment.py +165 -0
  42. trilogy/core/models/core.py +506 -0
  43. trilogy/core/models/datasource.py +434 -0
  44. trilogy/core/models/environment.py +756 -0
  45. trilogy/core/models/execute.py +1213 -0
  46. trilogy/core/optimization.py +251 -0
  47. trilogy/core/optimizations/__init__.py +12 -0
  48. trilogy/core/optimizations/base_optimization.py +17 -0
  49. trilogy/core/optimizations/hide_unused_concept.py +47 -0
  50. trilogy/core/optimizations/inline_datasource.py +102 -0
  51. trilogy/core/optimizations/predicate_pushdown.py +245 -0
  52. trilogy/core/processing/README.md +94 -0
  53. trilogy/core/processing/READMEv2.md +121 -0
  54. trilogy/core/processing/VIRTUAL_UNNEST.md +30 -0
  55. trilogy/core/processing/__init__.py +0 -0
  56. trilogy/core/processing/concept_strategies_v3.py +508 -0
  57. trilogy/core/processing/constants.py +15 -0
  58. trilogy/core/processing/discovery_node_factory.py +451 -0
  59. trilogy/core/processing/discovery_utility.py +548 -0
  60. trilogy/core/processing/discovery_validation.py +167 -0
  61. trilogy/core/processing/graph_utils.py +43 -0
  62. trilogy/core/processing/node_generators/README.md +9 -0
  63. trilogy/core/processing/node_generators/__init__.py +31 -0
  64. trilogy/core/processing/node_generators/basic_node.py +160 -0
  65. trilogy/core/processing/node_generators/common.py +270 -0
  66. trilogy/core/processing/node_generators/constant_node.py +38 -0
  67. trilogy/core/processing/node_generators/filter_node.py +315 -0
  68. trilogy/core/processing/node_generators/group_node.py +213 -0
  69. trilogy/core/processing/node_generators/group_to_node.py +117 -0
  70. trilogy/core/processing/node_generators/multiselect_node.py +207 -0
  71. trilogy/core/processing/node_generators/node_merge_node.py +695 -0
  72. trilogy/core/processing/node_generators/recursive_node.py +88 -0
  73. trilogy/core/processing/node_generators/rowset_node.py +165 -0
  74. trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
  75. trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +261 -0
  76. trilogy/core/processing/node_generators/select_merge_node.py +786 -0
  77. trilogy/core/processing/node_generators/select_node.py +95 -0
  78. trilogy/core/processing/node_generators/synonym_node.py +98 -0
  79. trilogy/core/processing/node_generators/union_node.py +91 -0
  80. trilogy/core/processing/node_generators/unnest_node.py +182 -0
  81. trilogy/core/processing/node_generators/window_node.py +201 -0
  82. trilogy/core/processing/nodes/README.md +28 -0
  83. trilogy/core/processing/nodes/__init__.py +179 -0
  84. trilogy/core/processing/nodes/base_node.py +522 -0
  85. trilogy/core/processing/nodes/filter_node.py +75 -0
  86. trilogy/core/processing/nodes/group_node.py +194 -0
  87. trilogy/core/processing/nodes/merge_node.py +420 -0
  88. trilogy/core/processing/nodes/recursive_node.py +46 -0
  89. trilogy/core/processing/nodes/select_node_v2.py +242 -0
  90. trilogy/core/processing/nodes/union_node.py +53 -0
  91. trilogy/core/processing/nodes/unnest_node.py +62 -0
  92. trilogy/core/processing/nodes/window_node.py +56 -0
  93. trilogy/core/processing/utility.py +823 -0
  94. trilogy/core/query_processor.py +604 -0
  95. trilogy/core/statements/README.md +35 -0
  96. trilogy/core/statements/__init__.py +0 -0
  97. trilogy/core/statements/author.py +536 -0
  98. trilogy/core/statements/build.py +0 -0
  99. trilogy/core/statements/common.py +20 -0
  100. trilogy/core/statements/execute.py +155 -0
  101. trilogy/core/table_processor.py +66 -0
  102. trilogy/core/utility.py +8 -0
  103. trilogy/core/validation/README.md +46 -0
  104. trilogy/core/validation/__init__.py +0 -0
  105. trilogy/core/validation/common.py +161 -0
  106. trilogy/core/validation/concept.py +146 -0
  107. trilogy/core/validation/datasource.py +227 -0
  108. trilogy/core/validation/environment.py +73 -0
  109. trilogy/core/validation/fix.py +256 -0
  110. trilogy/dialect/__init__.py +32 -0
  111. trilogy/dialect/base.py +1431 -0
  112. trilogy/dialect/bigquery.py +314 -0
  113. trilogy/dialect/common.py +147 -0
  114. trilogy/dialect/config.py +159 -0
  115. trilogy/dialect/dataframe.py +50 -0
  116. trilogy/dialect/duckdb.py +376 -0
  117. trilogy/dialect/enums.py +149 -0
  118. trilogy/dialect/metadata.py +173 -0
  119. trilogy/dialect/mock.py +190 -0
  120. trilogy/dialect/postgres.py +117 -0
  121. trilogy/dialect/presto.py +110 -0
  122. trilogy/dialect/results.py +89 -0
  123. trilogy/dialect/snowflake.py +129 -0
  124. trilogy/dialect/sql_server.py +137 -0
  125. trilogy/engine.py +48 -0
  126. trilogy/execution/__init__.py +17 -0
  127. trilogy/execution/config.py +119 -0
  128. trilogy/execution/state/__init__.py +0 -0
  129. trilogy/execution/state/file_state_store.py +0 -0
  130. trilogy/execution/state/sqllite_state_store.py +0 -0
  131. trilogy/execution/state/state_store.py +301 -0
  132. trilogy/executor.py +656 -0
  133. trilogy/hooks/__init__.py +4 -0
  134. trilogy/hooks/base_hook.py +40 -0
  135. trilogy/hooks/graph_hook.py +135 -0
  136. trilogy/hooks/query_debugger.py +166 -0
  137. trilogy/metadata/__init__.py +0 -0
  138. trilogy/parser.py +10 -0
  139. trilogy/parsing/README.md +21 -0
  140. trilogy/parsing/__init__.py +0 -0
  141. trilogy/parsing/common.py +1069 -0
  142. trilogy/parsing/config.py +5 -0
  143. trilogy/parsing/exceptions.py +8 -0
  144. trilogy/parsing/helpers.py +1 -0
  145. trilogy/parsing/parse_engine.py +2863 -0
  146. trilogy/parsing/render.py +773 -0
  147. trilogy/parsing/trilogy.lark +544 -0
  148. trilogy/py.typed +0 -0
  149. trilogy/render.py +45 -0
  150. trilogy/scripts/README.md +9 -0
  151. trilogy/scripts/__init__.py +0 -0
  152. trilogy/scripts/agent.py +41 -0
  153. trilogy/scripts/agent_info.py +306 -0
  154. trilogy/scripts/common.py +430 -0
  155. trilogy/scripts/dependency/Cargo.lock +617 -0
  156. trilogy/scripts/dependency/Cargo.toml +39 -0
  157. trilogy/scripts/dependency/README.md +131 -0
  158. trilogy/scripts/dependency/build.sh +25 -0
  159. trilogy/scripts/dependency/src/directory_resolver.rs +387 -0
  160. trilogy/scripts/dependency/src/lib.rs +16 -0
  161. trilogy/scripts/dependency/src/main.rs +770 -0
  162. trilogy/scripts/dependency/src/parser.rs +435 -0
  163. trilogy/scripts/dependency/src/preql.pest +208 -0
  164. trilogy/scripts/dependency/src/python_bindings.rs +311 -0
  165. trilogy/scripts/dependency/src/resolver.rs +716 -0
  166. trilogy/scripts/dependency/tests/base.preql +3 -0
  167. trilogy/scripts/dependency/tests/cli_integration.rs +377 -0
  168. trilogy/scripts/dependency/tests/customer.preql +6 -0
  169. trilogy/scripts/dependency/tests/main.preql +9 -0
  170. trilogy/scripts/dependency/tests/orders.preql +7 -0
  171. trilogy/scripts/dependency/tests/test_data/base.preql +9 -0
  172. trilogy/scripts/dependency/tests/test_data/consumer.preql +1 -0
  173. trilogy/scripts/dependency.py +323 -0
  174. trilogy/scripts/display.py +555 -0
  175. trilogy/scripts/environment.py +59 -0
  176. trilogy/scripts/fmt.py +32 -0
  177. trilogy/scripts/ingest.py +472 -0
  178. trilogy/scripts/ingest_helpers/__init__.py +1 -0
  179. trilogy/scripts/ingest_helpers/foreign_keys.py +123 -0
  180. trilogy/scripts/ingest_helpers/formatting.py +93 -0
  181. trilogy/scripts/ingest_helpers/typing.py +161 -0
  182. trilogy/scripts/init.py +105 -0
  183. trilogy/scripts/parallel_execution.py +748 -0
  184. trilogy/scripts/plan.py +189 -0
  185. trilogy/scripts/refresh.py +106 -0
  186. trilogy/scripts/run.py +79 -0
  187. trilogy/scripts/serve.py +202 -0
  188. trilogy/scripts/serve_helpers/__init__.py +41 -0
  189. trilogy/scripts/serve_helpers/file_discovery.py +142 -0
  190. trilogy/scripts/serve_helpers/index_generation.py +206 -0
  191. trilogy/scripts/serve_helpers/models.py +38 -0
  192. trilogy/scripts/single_execution.py +131 -0
  193. trilogy/scripts/testing.py +129 -0
  194. trilogy/scripts/trilogy.py +75 -0
  195. trilogy/std/__init__.py +0 -0
  196. trilogy/std/color.preql +3 -0
  197. trilogy/std/date.preql +13 -0
  198. trilogy/std/display.preql +18 -0
  199. trilogy/std/geography.preql +22 -0
  200. trilogy/std/metric.preql +15 -0
  201. trilogy/std/money.preql +67 -0
  202. trilogy/std/net.preql +14 -0
  203. trilogy/std/ranking.preql +7 -0
  204. trilogy/std/report.preql +5 -0
  205. trilogy/std/semantic.preql +6 -0
  206. trilogy/utility.py +34 -0
@@ -0,0 +1,544 @@
1
+ !start: ( block | show_statement | PARSE_COMMENT )*
2
+ block: statement _TERMINATOR LINE_SEPARATOR? PARSE_COMMENT*
3
+ ?statement: concept
4
+ | datasource
5
+ | function
6
+ | type_declaration
7
+ | multi_select_statement
8
+ | select_statement
9
+ | persist_statement
10
+ | rowset_derivation_statement
11
+ | import_statement
12
+ | copy_statement
13
+ | merge_statement
14
+ | rawsql_statement
15
+ | validate_statement
16
+ | mock_statement
17
+ | publish_statement
18
+ | create_statement
19
+
20
+ _TERMINATOR: ";"i
21
+
22
+ PARSE_COMMENT.1: /#.*(\n|$)/ | /\/\/.*(\n|$)/
23
+
24
+ // when whitespace matters - comment placement
25
+ LINE_SEPARATOR.1: /[ \t\r\f\v]*\n+/
26
+
27
+ // property display_name string
28
+ concept_declaration: PURPOSE IDENTIFIER data_type concept_nullable_modifier? metadata?
29
+ //customer_id.property first_name STRING;
30
+ //<customer_id,country>.property local_alias STRING
31
+ UNIQUE: "UNIQUE"i
32
+ concept_property_declaration: UNIQUE? PROPERTY (prop_ident | IDENTIFIER) data_type concept_nullable_modifier? metadata?
33
+ //metric post_length <- len(post_text);
34
+ concept_derivation: (PURPOSE | AUTO | PROPERTY ) (prop_ident | IDENTIFIER) "<-" expr
35
+
36
+ rowset_derivation_statement: ("rowset"i IDENTIFIER "<-" (multi_select_statement | select_statement)) | ("with"i IDENTIFIER "as"i (multi_select_statement | select_statement))
37
+
38
+ constant_derivation: CONST IDENTIFIER "<-" (literal | _constant_functions)
39
+
40
+ concept_nullable_modifier: "?"
41
+ concept: (concept_declaration | concept_derivation | concept_property_declaration | constant_derivation)
42
+
43
+ //concept property
44
+ prop_ident: "<" IDENTIFIER ("," IDENTIFIER )* ","? ">" "." IDENTIFIER
45
+
46
+ // datasource concepts
47
+ DATASOURCE_STATUS: "published"i | "unpublished"i
48
+ DATASOURCE_ROOT: "root"i
49
+
50
+ datasource_status_clause: /state/i DATASOURCE_STATUS
51
+
52
+ datasource_increment_clause: "incremental"i "by"i column_list
53
+
54
+ datasource_partition_clause: "partition"i "by"i column_list
55
+
56
+ datasource: DATASOURCE_ROOT? "datasource" IDENTIFIER "(" column_assignment_list ")" grain_clause? whole_grain_clause? (address | query | file) where? datasource_increment_clause? datasource_partition_clause? datasource_status_clause?
57
+
58
+ whole_grain_clause: "complete" where
59
+
60
+ grain_clause: "grain" "(" column_list ")"
61
+
62
+ address: "address" (QUOTED_ADDRESS | ADDRESS)
63
+
64
+ query: "query" MULTILINE_STRING
65
+
66
+ file: "file" FILE_PATH
67
+
68
+ concept_assignment: SHORTHAND_MODIFIER* IDENTIFIER
69
+
70
+ //column_assignment
71
+ //figure out if we want static
72
+ column_assignment: ((raw_column_assignment | IDENTIFIER | QUOTED_IDENTIFIER | expr ) ":" concept_assignment) | concept_assignment
73
+
74
+ RAW_ENTRY.1: /raw\s*\(/s
75
+
76
+ raw_column_assignment: RAW_ENTRY MULTILINE_STRING ")"
77
+
78
+ column_assignment_list : column_assignment ("," column_assignment)* ","?
79
+
80
+ column_list : (IDENTIFIER "," )* IDENTIFIER ","?
81
+
82
+ IMPORT_DOT: "."
83
+
84
+ import_statement: "import" IMPORT_DOT* IDENTIFIER ("." IDENTIFIER)* ("as" IDENTIFIER)?
85
+
86
+ // persist_statement
87
+ PERSIST_MODE: "append"i | "overwrite"i | "persist"i
88
+ persist_partition_clause: "by"i column_list
89
+
90
+ // short persist with auto query
91
+ auto_persist: PERSIST_MODE IDENTIFIER where?
92
+
93
+ // full persist with query
94
+ full_persist: PERSIST_MODE IDENTIFIER? "into"i IDENTIFIER persist_partition_clause? "from"i select_statement
95
+
96
+ persist_statement: auto_persist | full_persist
97
+
98
+ // select statement
99
+ select_statement: where? "select"i select_list where? having? order_by? limit?
100
+
101
+ // multiple_selects
102
+ multi_select_statement: select_statement ("merge" select_statement)+ "align"i align_clause ("derive" derive_clause)? where? order_by? limit?
103
+
104
+ align_item: IDENTIFIER ":" IDENTIFIER ("," IDENTIFIER)* ","?
105
+
106
+ align_clause: align_item ("AND"i align_item)* "AND"i?
107
+
108
+ derive_item: expr "->" IDENTIFIER
109
+
110
+ derive_clause: derive_item ("," derive_item)* ","?
111
+
112
+ merge_statement: "merge"i WILDCARD_IDENTIFIER "into"i SHORTHAND_MODIFIER? WILDCARD_IDENTIFIER
113
+
114
+ // raw sql statement
115
+ rawsql_statement: "raw_sql"i "(" MULTILINE_STRING ")"
116
+
117
+ // validate_statement
118
+
119
+ VALIDATE_SCOPE: "concepts"i | "datasources"i | "datasource"i | "concept"i
120
+
121
+ validate_statement: ("validate"i "all"i) | ( "validate"i VALIDATE_SCOPE (IDENTIFIER ("," IDENTIFIER)* ","? )? )
122
+
123
+ // mock statement
124
+
125
+ mock_statement: "mock"i VALIDATE_SCOPE (IDENTIFIER ("," IDENTIFIER)* ","? )?
126
+
127
+ // publish statement
128
+ PUBLISH_ACTION : "publish"i | "unpublish"i
129
+ publish_statement: PUBLISH_ACTION VALIDATE_SCOPE IDENTIFIER
130
+
131
+ // create_statement
132
+ CREATE_IF_NOT_EXISTS: /if\s+not\s+exists/i
133
+ CREATE_OR_REPLACE: /or\s+replace/i
134
+
135
+ create_modifier_clause: CREATE_IF_NOT_EXISTS | CREATE_OR_REPLACE
136
+ create_statement: "create"i create_modifier_clause? VALIDATE_SCOPE IDENTIFIER
137
+
138
+ // copy statement
139
+
140
+ COPY_TYPE: "csv"i | "parquet"i
141
+
142
+ copy_statement: "copy"i "into"i COPY_TYPE string_lit "from"i select_statement
143
+
144
+ // FUNCTION blocks
145
+ function: raw_function
146
+ function_binding_type: ":" data_type
147
+ function_binding_default: /=/ expr
148
+ function_binding_item: IDENTIFIER function_binding_type? function_binding_default?
149
+ function_binding_list: (function_binding_item ",")* function_binding_item ","?
150
+ raw_function: "def" IDENTIFIER "(" function_binding_list ")" "->" expr
151
+
152
+ // TYPE blocks
153
+ type_drop_clause: "DROP" IDENTIFIER ("|" IDENTIFIER)*
154
+ //type_add_clause: "ADD" IDENTIFIER ("|" IDENTIFIER)* type_add_clause?
155
+ type_declaration: "type" IDENTIFIER data_type ("|" data_type)* type_drop_clause?
156
+
157
+ // user_id where state = Mexico
158
+ _filter_alt: (IDENTIFIER | literal | _static_functions | "(" expr ")") "?" conditional
159
+ _filter_base: "filter"i IDENTIFIER where
160
+ filter_item: _filter_base | _filter_alt
161
+
162
+ // rank/lag/lead
163
+ WINDOW_TYPE: ("row_number"i|"rank"i|"lag"i|"lead"i | "sum"i | "avg"i | "max"i | "min"i | "count"i ) /[\s]+/
164
+
165
+ window_item_over: ("OVER"i over_list)
166
+
167
+ window_item_order: ("ORDER"i? "BY"i order_list)
168
+
169
+ window_item: WINDOW_TYPE int_lit? expr window_item_over? window_item_order?
170
+
171
+ select_hide_modifier: "--"
172
+ select_partial_modifier: "~"
173
+ select_item: (select_hide_modifier | select_partial_modifier)? (concept_lit | select_transform )
174
+
175
+ select_list: select_item ("," select_item )* ","?
176
+
177
+ // count(post_id) -> post_count
178
+ _assignment: ("->") | "as"i
179
+ select_transform : expr _assignment IDENTIFIER metadata?
180
+
181
+ metadata: "metadata" "(" IDENTIFIER "=" string_lit ")"
182
+
183
+ limit: "LIMIT"i /[0-9]+/
184
+
185
+ ORDER_IDENTIFIER.2: /(?!LIMIT)[a-zA-Z_][a-zA-Z0-9_\.]*\s+/
186
+ _order_atom: (ORDER_IDENTIFIER ordering) | (expr ordering)
187
+
188
+ order_list: _order_atom ("," _order_atom)* ","?
189
+
190
+ over_component: /,\s*[a-zA-Z\_][a-zA-Z0-9\_\.]*/ "END"?
191
+
192
+ over_list: concept_lit over_component*
193
+
194
+ ORDERING_DIRECTION: /ASC|DESC/i
195
+
196
+ !ordering: ORDERING_DIRECTION ("NULLS"i /FIRST|LAST|AUTO/i )?
197
+
198
+ order_by: "ORDER"i "BY"i order_list
199
+
200
+ //WHERE STATEMENT
201
+ LOGICAL_OR: "or"i
202
+ LOGICAL_AND: "and"i
203
+
204
+ conditional: _or_condition
205
+
206
+ _or_condition: _and_condition
207
+ | (_or_condition LOGICAL_OR _and_condition)
208
+
209
+ _and_condition: _condition_unit
210
+ | (_and_condition LOGICAL_AND _condition_unit)
211
+
212
+ CONDITION_NOT: "NOT"i
213
+ condition_parenthetical: CONDITION_NOT? "(" conditional ")"
214
+
215
+ _condition_unit: expr
216
+ | condition_parenthetical
217
+
218
+ where: "WHERE"i conditional
219
+
220
+ having: "HAVING"i conditional
221
+
222
+ !array_comparison: ( ("NOT"i "IN"i) | "IN"i)
223
+
224
+ COMPARISON_OPERATOR: /(\s+is\s+not\s|\s+is\s|\s+in\s|\s+not\s+in\s|=|>=|<=|!=|>|<)/i
225
+
226
+ between_comparison: "between"i expr "and"i expr
227
+
228
+ subselect_comparison: expr array_comparison (literal | _constant_functions | _string_functions | _array_functions | concept_lit | filter_item | window_item | unnest | fgroup | expr_tuple | parenthetical )
229
+
230
+ expr_tuple: ("(" expr ("," expr)+ ","? ")") | ("(" expr "," ")")
231
+
232
+ parenthetical: "(" expr ")"
233
+
234
+ //unnesting is a function
235
+ _UNNEST.1: "UNNEST("i
236
+ unnest: _UNNEST expr ")"
237
+
238
+ // union statement
239
+ _UNION.1: "UNION("i
240
+ union: _UNION (expr ",")* expr ")"
241
+
242
+ //indexing into an expression is a function
243
+ index_access: atom "[" int_lit "]"
244
+ map_key_access: atom "[" string_lit "]"
245
+ _ATTR_ACCESS.1 : "getattr("i
246
+ attr_access: ( _ATTR_ACCESS atom "," string_lit ")") | (atom "." string_lit)
247
+
248
+ ?expr: comparison_root | between_root
249
+
250
+ ?comparison_root: sum_chain (COMPARISON_OPERATOR sum_chain)? -> comparison
251
+ ?between_root: sum_chain "between"i sum_chain "and"i sum_chain -> between_comparison
252
+
253
+ PLUS_OR_MINUS: ("+" | /-(?!>)/ | "||" | "like" )
254
+
255
+ ?sum_chain: product_chain (PLUS_OR_MINUS product_chain)* -> sum_operator
256
+
257
+ MULTIPLY_DIVIDE_PERCENT: ("**" | "*" | "/" | "%")
258
+
259
+ ?product_chain: atom ( MULTIPLY_DIVIDE_PERCENT atom)* -> product_operator
260
+
261
+ ?atom: literal | concept_lit | parenthetical
262
+ | expr_tuple
263
+ | custom_function
264
+ | _constant_functions
265
+ | _static_functions
266
+ | _generic_functions
267
+ | _date_functions
268
+ | aggregate_functions
269
+ | window_item
270
+ | unnest
271
+ | union
272
+ | fgroup
273
+ | filter_item
274
+ | _access_expr
275
+ | aggregate_by
276
+
277
+
278
+ # Access patterns
279
+ _access_expr: index_access | map_key_access | attr_access
280
+ // functions
281
+
282
+ fadd: (/add\(/ expr "," expr ")" )
283
+ fsub: ("subtract"i "(" expr "," expr ")" )
284
+ fmul: ("multiply"i "(" expr "," expr ")" )
285
+ fdiv: ( "divide"i "(" expr "," expr ")")
286
+ fmod: ( "mod"i "(" expr "," (int_lit | concept_lit ) ")")
287
+ _LOG.1: "log"i "("
288
+ flog: _LOG expr ("," expr)? ")"
289
+ _ROUND.1: "round"i "("
290
+ fround: _ROUND expr ("," expr)? ")"
291
+ _FLOOR.1: "floor"i "("
292
+ ffloor: _FLOOR expr ")"
293
+ _CEIL.1: "ceil"i "("
294
+ fceil: _CEIL expr ")"
295
+ fabs: "abs"i "(" expr ")"
296
+ _SQRT.1: "sqrt("
297
+ fsqrt: _SQRT expr ")"
298
+ _RANDOM.1: "random("i
299
+ frandom: _RANDOM expr ")"
300
+
301
+ _math_functions: fmul | fdiv | fadd | fsub | fround | ffloor | fceil | fmod | flog | fabs | fsqrt | frandom
302
+
303
+ //generic
304
+ _fcast_primary: "cast"i "(" expr "as"i data_type ")"
305
+ _fcast_alt: atom "::" data_type
306
+ fcast: _fcast_primary | _fcast_alt
307
+ concat: ("concat"i "(" (expr ",")* expr ")")
308
+ fcoalesce: "coalesce"i "(" (expr ",")* expr ")"
309
+ fcase_when: "WHEN"i conditional "THEN"i expr
310
+ fcase_else: "ELSE"i expr
311
+ fcase: "CASE"i (fcase_when)* (fcase_else)? "END"i
312
+ len: "len"i "(" expr ")"
313
+ fnot: "NOT"i expr
314
+ fbool: "bool"i "(" expr ")"
315
+ fnullif: "nullif"i "(" expr "," expr ")"
316
+ _FRECURSE_EDGE.1: "recurse_edge("i
317
+ frecurse_edge: _FRECURSE_EDGE expr "," expr ")"
318
+
319
+ _generic_functions: fcast | concat | fcoalesce | fnullif | fcase | len | fnot | fbool | frecurse_edge
320
+
321
+ //constant
322
+ CURRENT_DATE.1: /current_date\(\)/
323
+ CURRENT_DATETIME.1: /current_datetime\(\)/
324
+ CURRENT_TIMESTAMP.1: /current_timestamp\(\)/
325
+ fcurrent_date: CURRENT_DATE
326
+ fcurrent_datetime: CURRENT_DATETIME
327
+ fcurrent_timestamp: CURRENT_TIMESTAMP
328
+
329
+ _constant_functions: fcurrent_date | fcurrent_datetime | fcurrent_timestamp
330
+
331
+ //string
332
+ _LIKE.1: "like("i
333
+ like: _LIKE expr "," string_lit ")"
334
+ _ILIKE.1: "ilike("i
335
+ ilike: _ILIKE expr "," string_lit ")"
336
+ alt_like: expr "like"i expr
337
+ _UPPER.1: "upper("i
338
+ upper: _UPPER expr ")"
339
+ _LOWER.1: "lower("i
340
+ flower: _LOWER expr ")"
341
+ _SPLIT.1: "split("i
342
+ fsplit: _SPLIT expr "," string_lit ")"
343
+ _STRPOS.1: "strpos("i
344
+ fstrpos: _STRPOS expr "," expr ")"
345
+ _CONTAINS.1: "contains("i
346
+ fcontains: _CONTAINS expr "," expr ")"
347
+ _TRIM.1: "trim("i
348
+ ftrim: _TRIM expr ")"
349
+ _REPLACE.1: "replace("i
350
+ freplace: _REPLACE expr "," expr "," expr ")"
351
+ _SUBSTRING.1: "substring("i
352
+ fsubstring: _SUBSTRING expr "," expr "," expr ")"
353
+ _REGEXP_EXTRACT.1: "regexp_extract("
354
+ fregexp_extract: _REGEXP_EXTRACT expr "," expr ("," int_lit)? ")"
355
+ _REGEXP_CONTAINS.1: "regexp_contains("
356
+ fregexp_contains: _REGEXP_CONTAINS expr "," expr ")"
357
+ _REGEXP_REPLACE.1: "regexp_replace("
358
+ fregexp_replace: _REGEXP_REPLACE expr "," expr "," expr ")"
359
+ _HASH.1: "hash("
360
+ HASH_TYPE: "md5"i | "sha1"i | "sha256"i | "sha512"i
361
+ fhash: _HASH expr "," HASH_TYPE ")"
362
+
363
+ _string_functions: like | ilike | upper | flower | fsplit | fstrpos | fsubstring | fcontains | ftrim | freplace | fregexp_extract | fregexp_contains | fregexp_replace | fhash
364
+
365
+ //array_functions
366
+ _ARRAY_SUM.1: "array_sum("i
367
+ farray_sum: _ARRAY_SUM expr ")"
368
+ _ARRAY_DISTINCT.1: "array_distinct("i
369
+ farray_distinct: _ARRAY_DISTINCT expr ")"
370
+ _ARRAY_TO_STRING.1: "array_to_string("i
371
+ farray_to_string: _ARRAY_TO_STRING expr "," expr ")"
372
+ _ARRAY_SORT.1: "array_sort("i
373
+ farray_sort: _ARRAY_SORT expr ("," ordering )? ")"
374
+ _ARRAY_TRANSFORM.1: "array_transform("i
375
+ transform_lambda: "@" IDENTIFIER
376
+ farray_transform: _ARRAY_TRANSFORM expr "," transform_lambda ")"
377
+ _ARRAY_FILTER.1: "array_filter("i
378
+ farray_filter: _ARRAY_FILTER expr "," transform_lambda ")"
379
+ _GENERATE_ARRAY.1: "generate_array("i
380
+ fgenerate_array: _GENERATE_ARRAY expr "," expr "," expr ")"
381
+
382
+ _array_functions: farray_sum | farray_distinct | farray_sort | farray_transform | farray_to_string | farray_filter | fgenerate_array
383
+
384
+ //map_functions
385
+ _MAP_KEYS.1: "map_keys("i
386
+ fmap_keys: _MAP_KEYS expr ")"
387
+ _MAP_VALUES.1: "map_values("i
388
+ fmap_values: _MAP_VALUES expr ")"
389
+
390
+ _map_functions: fmap_keys | fmap_values
391
+
392
+ // special aggregate
393
+ _GROUP.1: "group("i
394
+ fgroup: _GROUP expr ")" aggregate_over?
395
+
396
+ //by:
397
+ aggregate_by: /(group)\s+([a-zA-Z\_][a-zA-Z0-9\_\.]*)/i "BY"i (IDENTIFIER ",")* IDENTIFIER
398
+
399
+ //aggregates
400
+ _COUNT.1: "count("i
401
+ count: _COUNT expr ")"
402
+
403
+ count_distinct: "count_distinct"i "(" expr ")"
404
+
405
+ // avoid conflicts with the window
406
+ _SUM.1: "sum("i
407
+ sum: _SUM expr ")"
408
+ _AVG.1: "avg("i
409
+ avg: _AVG expr ")"
410
+ _MAX.1: "max("i
411
+ max: _MAX expr ")"
412
+ _MIN.1: "min("i
413
+ min: _MIN expr ")"
414
+ _ARRAY_AGG.1: "array_agg("i
415
+ array_agg: _ARRAY_AGG expr ")"
416
+ _BOOL_OR.1: "bool_or("i
417
+ bool_or: _BOOL_OR expr ")"
418
+ _BOOL_AND.1: "bool_and("i
419
+ bool_and: _BOOL_AND expr ")"
420
+ _ANY.1: "any("i
421
+ any: _ANY expr ")"
422
+
423
+ //aggregates can force a grain
424
+ aggregate_all: "*"
425
+ aggregate_over: ("BY"i (aggregate_all | over_list))
426
+ aggregate_functions: (count | count_distinct | sum | avg | max | min | array_agg | bool_and | bool_or | any) aggregate_over?
427
+
428
+ // date functions
429
+ _DATE.1: "date("i
430
+ fdate: _DATE expr ")"
431
+ fdatetime: "datetime"i "(" expr ")"
432
+ _TIMESTAMP.1: "timestamp("i
433
+ ftimestamp: _TIMESTAMP expr ")"
434
+
435
+ _SECOND.1: "second("i
436
+ fsecond: _SECOND expr ")"
437
+ _MINUTE.1: "minute("i
438
+ fminute: _MINUTE expr ")"
439
+ _HOUR.1: "hour("i
440
+ fhour: _HOUR expr ")"
441
+ _DAY.1: "day("i
442
+ fday: _DAY expr ")"
443
+ _DAY_NAME.1: "day_name("i
444
+ fday_name: _DAY_NAME expr ")"
445
+ _DAY_OF_WEEK.1: "day_of_week("i
446
+ fday_of_week: _DAY_OF_WEEK expr ")"
447
+ _WEEK.1: "week("i
448
+ fweek: _WEEK expr ")"
449
+ _MONTH.1: "month("i
450
+ fmonth: _MONTH expr ")"
451
+ _MONTH_NAME.1: "month_name("i
452
+ fmonth_name: _MONTH_NAME expr ")"
453
+ _QUARTER.1: "quarter("i
454
+ fquarter: _QUARTER expr ")"
455
+ _YEAR.1: "year("i
456
+ fyear: _YEAR expr ")"
457
+
458
+ DATE_PART: "DAY"i | "WEEK"i | "MONTH"i | "QUARTER"i | "YEAR"i | "MINUTE"i | "HOUR"i | "SECOND"i | "DAY_OF_WEEK"i
459
+ _DATE_TRUNC.1: "date_trunc("i | "date_truncate("i
460
+ fdate_trunc: _DATE_TRUNC expr "," DATE_PART ")"
461
+ _DATE_PART.1: "date_part("i
462
+ fdate_part: _DATE_PART expr "," DATE_PART ")"
463
+ _DATE_ADD.1: "date_add("i
464
+ fdate_add: _DATE_ADD expr "," DATE_PART "," expr ")"
465
+ _DATE_SUB.1: "date_sub("i
466
+ fdate_sub: _DATE_SUB expr "," DATE_PART "," expr ")"
467
+ _DATE_DIFF.1: "date_diff("i
468
+ fdate_diff: _DATE_DIFF expr "," expr "," DATE_PART ")"
469
+ _DATE_SPINE.1: "date_spine("i
470
+ fdate_spine: _DATE_SPINE expr "," expr ")"
471
+
472
+ _date_functions: fdate | fdate_add | fdate_sub | fdate_diff | fdatetime | ftimestamp | fsecond | fminute | fhour | fday |fday_name | fday_of_week | fweek | fmonth | fmonth_name | fquarter | fyear | fdate_part | fdate_trunc | fdate_spine
473
+
474
+ _static_functions: _string_functions | _math_functions | _array_functions | _map_functions
475
+
476
+ custom_function: "@" IDENTIFIER "(" (expr ",")* expr ")"
477
+
478
+ // base language constructs
479
+ concept_lit: IDENTIFIER
480
+ IDENTIFIER: /[a-zA-Z\_][a-zA-Z0-9\_\.]*/
481
+ WILDCARD_IDENTIFIER: /[a-zA-Z\_][a-zA-Z0-9\_\-\.\*]*/
482
+ QUOTED_IDENTIFIER: /`[a-zA-Z\_][a-zA-Z0-9\_\.\-\*\:\s]*`/
483
+ QUOTED_ADDRESS: /`'?[a-zA-Z\_\\\/][a-zA-Z0-9\_\.\\\/\-\*\:\s]*'?`/
484
+ ADDRESS: IDENTIFIER
485
+
486
+ MULTILINE_STRING: /\'{3}(.*?)\'{3}/s
487
+ FILE_PATH: /`[^`]+\.(py|csv|parquet|tsv|sql)`/i
488
+
489
+ DOUBLE_STRING_CHARS: /(?:(?!\${)([^"\\]|\\.))+/+ // any character except "
490
+ SINGLE_STRING_CHARS: /(?:(?!\${)([^'\\]|\\.))+/+ // any character except '
491
+ _single_quote: "'" ( SINGLE_STRING_CHARS )* "'"
492
+ _double_quote: "\"" ( DOUBLE_STRING_CHARS )* "\""
493
+ string_lit: _single_quote | _double_quote | MULTILINE_STRING
494
+
495
+
496
+
497
+ int_lit: /\-?[0-9]+/
498
+
499
+ float_lit: /\-?[0-9]*\.[0-9]+/
500
+
501
+ array_lit: "[" (expr ",")* expr ","? "]"()
502
+
503
+ tuple_lit: "(" (literal ",")* literal ","? ")"
504
+
505
+ map_lit: "{" (literal ":" literal ",")* literal ":" literal ","? "}"
506
+
507
+ _STRUCT.1: "struct("i
508
+ _BINDING.1: "->"
509
+ struct_lit: _STRUCT expr _BINDING IDENTIFIER ( "," expr _BINDING IDENTIFIER )* ","? ")"
510
+
511
+ !bool_lit: "True"i | "False"i
512
+
513
+ !null_lit.1: "null"i
514
+
515
+ literal: null_lit | string_lit | int_lit | float_lit | bool_lit | array_lit | map_lit | struct_lit | tuple_lit
516
+
517
+ MODIFIER: /OPTIONAL|PARTIAL|NULLABLE/i
518
+
519
+ SHORTHAND_MODIFIER: /~|\?/
520
+ struct_component: IDENTIFIER ":" data_type concept_nullable_modifier? metadata?
521
+ struct_type: "struct"i "<" ((struct_component | IDENTIFIER) ",")* (struct_component | IDENTIFIER) ","? ">"
522
+
523
+ list_type: ("list"i | "array"i) "<" (data_type | IDENTIFIER) ">"
524
+
525
+ numeric_type: "numeric"i "(" int_lit "," int_lit ")"
526
+
527
+ map_type: "map"i "<" (data_type | IDENTIFIER) "," (data_type | IDENTIFIER) ">"
528
+
529
+ !data_type: ("string"i | "number"i | "numeric"i | "map"i | "list"i | "array"i | "any"i | "int"i | "bigint"i | "date"i | "datetime"i | "timestamp"i | "float"i | "bool"i | numeric_type | map_type | struct_type | list_type) ("::" IDENTIFIER)?
530
+
531
+ PURPOSE: "key"i | "metric"i | "parameter"i | "param"i | CONST
532
+ PROPERTY: "property"i
533
+ CONST: "const"i | "constant"i
534
+ AUTO: "AUTO"i
535
+ // meta functions
536
+ CONCEPTS: "CONCEPTS"i
537
+ DATASOURCES: "DATASOURCES"i
538
+ show_category: CONCEPTS | DATASOURCES
539
+
540
+ show_statement: "show"i ( show_category | validate_statement | select_statement | persist_statement) _TERMINATOR
541
+ COMMENT: /#.*(\n|$)/ | /\/\/.*\n/
542
+ %import common.WS
543
+ %ignore WS
544
+ %ignore COMMENT
trilogy/py.typed ADDED
File without changes
trilogy/render.py ADDED
@@ -0,0 +1,45 @@
1
+ from trilogy.constants import Rendering
2
+ from trilogy.dialect.base import BaseDialect
3
+ from trilogy.dialect.config import DialectConfig
4
+ from trilogy.dialect.enums import Dialects
5
+
6
+
7
+ def get_dialect_generator(
8
+ dialect: Dialects,
9
+ rendering: Rendering | None = None,
10
+ config: DialectConfig | None = None,
11
+ ) -> BaseDialect:
12
+ if dialect == Dialects.BIGQUERY:
13
+ from trilogy.dialect.bigquery import BigqueryDialect
14
+
15
+ return BigqueryDialect(rendering=rendering, config=config)
16
+ elif dialect == Dialects.SQL_SERVER:
17
+ from trilogy.dialect.sql_server import SqlServerDialect
18
+
19
+ return SqlServerDialect(rendering=rendering, config=config)
20
+ elif dialect == Dialects.DUCK_DB:
21
+ from trilogy.dialect.duckdb import DuckDBDialect
22
+
23
+ return DuckDBDialect(rendering=rendering, config=config)
24
+ elif dialect == Dialects.PRESTO:
25
+ from trilogy.dialect.presto import PrestoDialect
26
+
27
+ return PrestoDialect(rendering=rendering, config=config)
28
+ elif dialect == Dialects.TRINO:
29
+ from trilogy.dialect.presto import TrinoDialect
30
+
31
+ return TrinoDialect(rendering=rendering, config=config)
32
+ elif dialect == Dialects.POSTGRES:
33
+ from trilogy.dialect.postgres import PostgresDialect
34
+
35
+ return PostgresDialect(rendering=rendering, config=config)
36
+ elif dialect == Dialects.SNOWFLAKE:
37
+ from trilogy.dialect.snowflake import SnowflakeDialect
38
+
39
+ return SnowflakeDialect(rendering=rendering, config=config)
40
+ elif dialect == Dialects.DATAFRAME:
41
+ from trilogy.dialect.dataframe import DataframeDialect
42
+
43
+ return DataframeDialect(rendering=rendering, config=config)
44
+ else:
45
+ raise ValueError(f"Unsupported dialect {dialect}")
@@ -0,0 +1,9 @@
1
+ # Trilogy CLI
2
+
3
+ Core entrypoint for CLI functions.
4
+
5
+ ## Local Testing
6
+
7
+ ```bash
8
+ python -m trilogy.scripts.trilogy unit C:\Users\ethan\coding_projects\pypreql\tests\scripts\validation_failure.preql
9
+ ```
File without changes
@@ -0,0 +1,41 @@
1
+ """Agent command for Trilogy CLI - AI-powered orchestration tasks."""
2
+
3
+ from click import argument, option, pass_context
4
+
5
+
6
+ @argument("command", type=str)
7
+ @option(
8
+ "--context",
9
+ "-c",
10
+ multiple=True,
11
+ help="Additional context files or paths for the agent",
12
+ )
13
+ @option("--model", "-m", type=str, help="AI model to use (if configured)")
14
+ @option(
15
+ "--interactive", "-i", is_flag=True, help="Run in interactive mode with feedback"
16
+ )
17
+ @pass_context
18
+ def agent(
19
+ ctx, command: str, context: tuple[str, ...], model: str | None, interactive: bool
20
+ ):
21
+ """Pass off a multi-step orchestration task to an AI agent.
22
+
23
+ This command allows you to delegate complex, multi-step tasks to a configured
24
+ AI agent. The agent can understand natural language commands and execute
25
+ a series of Trilogy operations to accomplish the goal.
26
+
27
+ Examples:
28
+ trilogy agent "analyze sales trends and create a dashboard"
29
+ trilogy agent "ingest new data and run validation tests"
30
+ trilogy agent "optimize query performance for customer reports"
31
+
32
+ Args:
33
+ command: Natural language command describing the task
34
+ context: Additional context files or paths to inform the agent
35
+ model: Specific AI model to use (requires configuration)
36
+ interactive: Enable interactive mode for step-by-step feedback
37
+ """
38
+ raise NotImplementedError(
39
+ "The 'agent' command is not yet implemented. "
40
+ "Configure an AI agent in your trilogy.toml to use this feature."
41
+ )