pytrilogy 0.3.149__cp313-cp313-win_amd64.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 (207) hide show
  1. LICENSE.md +19 -0
  2. _preql_import_resolver/__init__.py +5 -0
  3. _preql_import_resolver/_preql_import_resolver.cp313-win_amd64.pyd +0 -0
  4. pytrilogy-0.3.149.dist-info/METADATA +555 -0
  5. pytrilogy-0.3.149.dist-info/RECORD +207 -0
  6. pytrilogy-0.3.149.dist-info/WHEEL +4 -0
  7. pytrilogy-0.3.149.dist-info/entry_points.txt +2 -0
  8. pytrilogy-0.3.149.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 +2670 -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 +436 -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 +846 -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 +1432 -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 +397 -0
  117. trilogy/dialect/enums.py +151 -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/exceptions.py +26 -0
  130. trilogy/execution/state/file_state_store.py +0 -0
  131. trilogy/execution/state/sqllite_state_store.py +0 -0
  132. trilogy/execution/state/state_store.py +406 -0
  133. trilogy/executor.py +692 -0
  134. trilogy/hooks/__init__.py +4 -0
  135. trilogy/hooks/base_hook.py +40 -0
  136. trilogy/hooks/graph_hook.py +135 -0
  137. trilogy/hooks/query_debugger.py +166 -0
  138. trilogy/metadata/__init__.py +0 -0
  139. trilogy/parser.py +10 -0
  140. trilogy/parsing/README.md +21 -0
  141. trilogy/parsing/__init__.py +0 -0
  142. trilogy/parsing/common.py +1069 -0
  143. trilogy/parsing/config.py +5 -0
  144. trilogy/parsing/exceptions.py +8 -0
  145. trilogy/parsing/helpers.py +1 -0
  146. trilogy/parsing/parse_engine.py +2876 -0
  147. trilogy/parsing/render.py +775 -0
  148. trilogy/parsing/trilogy.lark +546 -0
  149. trilogy/py.typed +0 -0
  150. trilogy/render.py +45 -0
  151. trilogy/scripts/README.md +9 -0
  152. trilogy/scripts/__init__.py +0 -0
  153. trilogy/scripts/agent.py +41 -0
  154. trilogy/scripts/agent_info.py +306 -0
  155. trilogy/scripts/common.py +432 -0
  156. trilogy/scripts/dependency/Cargo.lock +617 -0
  157. trilogy/scripts/dependency/Cargo.toml +39 -0
  158. trilogy/scripts/dependency/README.md +131 -0
  159. trilogy/scripts/dependency/build.sh +25 -0
  160. trilogy/scripts/dependency/src/directory_resolver.rs +387 -0
  161. trilogy/scripts/dependency/src/lib.rs +16 -0
  162. trilogy/scripts/dependency/src/main.rs +770 -0
  163. trilogy/scripts/dependency/src/parser.rs +435 -0
  164. trilogy/scripts/dependency/src/preql.pest +208 -0
  165. trilogy/scripts/dependency/src/python_bindings.rs +311 -0
  166. trilogy/scripts/dependency/src/resolver.rs +716 -0
  167. trilogy/scripts/dependency/tests/base.preql +3 -0
  168. trilogy/scripts/dependency/tests/cli_integration.rs +377 -0
  169. trilogy/scripts/dependency/tests/customer.preql +6 -0
  170. trilogy/scripts/dependency/tests/main.preql +9 -0
  171. trilogy/scripts/dependency/tests/orders.preql +7 -0
  172. trilogy/scripts/dependency/tests/test_data/base.preql +9 -0
  173. trilogy/scripts/dependency/tests/test_data/consumer.preql +1 -0
  174. trilogy/scripts/dependency.py +323 -0
  175. trilogy/scripts/display.py +555 -0
  176. trilogy/scripts/environment.py +59 -0
  177. trilogy/scripts/fmt.py +32 -0
  178. trilogy/scripts/ingest.py +487 -0
  179. trilogy/scripts/ingest_helpers/__init__.py +1 -0
  180. trilogy/scripts/ingest_helpers/foreign_keys.py +123 -0
  181. trilogy/scripts/ingest_helpers/formatting.py +93 -0
  182. trilogy/scripts/ingest_helpers/typing.py +161 -0
  183. trilogy/scripts/init.py +105 -0
  184. trilogy/scripts/parallel_execution.py +762 -0
  185. trilogy/scripts/plan.py +189 -0
  186. trilogy/scripts/refresh.py +161 -0
  187. trilogy/scripts/run.py +79 -0
  188. trilogy/scripts/serve.py +202 -0
  189. trilogy/scripts/serve_helpers/__init__.py +41 -0
  190. trilogy/scripts/serve_helpers/file_discovery.py +142 -0
  191. trilogy/scripts/serve_helpers/index_generation.py +206 -0
  192. trilogy/scripts/serve_helpers/models.py +38 -0
  193. trilogy/scripts/single_execution.py +131 -0
  194. trilogy/scripts/testing.py +143 -0
  195. trilogy/scripts/trilogy.py +75 -0
  196. trilogy/std/__init__.py +0 -0
  197. trilogy/std/color.preql +3 -0
  198. trilogy/std/date.preql +13 -0
  199. trilogy/std/display.preql +18 -0
  200. trilogy/std/geography.preql +22 -0
  201. trilogy/std/metric.preql +15 -0
  202. trilogy/std/money.preql +67 -0
  203. trilogy/std/net.preql +14 -0
  204. trilogy/std/ranking.preql +7 -0
  205. trilogy/std/report.preql +5 -0
  206. trilogy/std/semantic.preql +6 -0
  207. trilogy/utility.py +34 -0
@@ -0,0 +1,546 @@
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_UPDATE_TRIGGER.2: "incremental"i | "freshness"i
53
+
54
+ datasource_update_trigger_clause: DATASOURCE_UPDATE_TRIGGER "by"i column_list
55
+
56
+ datasource_partition_clause: "partition"i "by"i column_list
57
+
58
+ datasource: DATASOURCE_ROOT? "datasource" IDENTIFIER "(" column_assignment_list ")" grain_clause? whole_grain_clause? (address | query | file) where? datasource_update_trigger_clause? datasource_partition_clause? datasource_status_clause?
59
+
60
+ whole_grain_clause: "complete" where
61
+
62
+ grain_clause: "grain" "(" column_list ")"
63
+
64
+ address: "address" (QUOTED_ADDRESS | ADDRESS)
65
+
66
+ query: "query" MULTILINE_STRING
67
+
68
+ file: "file" FILE_PATH
69
+
70
+ concept_assignment: SHORTHAND_MODIFIER* IDENTIFIER
71
+
72
+ //column_assignment
73
+ //figure out if we want static
74
+ column_assignment: ((raw_column_assignment | IDENTIFIER | QUOTED_IDENTIFIER | expr ) ":" concept_assignment) | concept_assignment
75
+
76
+ RAW_ENTRY.1: /raw\s*\(/s
77
+
78
+ raw_column_assignment: RAW_ENTRY MULTILINE_STRING ")"
79
+
80
+ column_assignment_list : column_assignment ("," column_assignment)* ","?
81
+
82
+ column_list : (IDENTIFIER "," )* IDENTIFIER ","?
83
+
84
+ IMPORT_DOT: "."
85
+
86
+ import_statement: "import" IMPORT_DOT* IDENTIFIER ("." IDENTIFIER)* ("as" IDENTIFIER)?
87
+
88
+ // persist_statement
89
+ PERSIST_MODE: "append"i | "overwrite"i | "persist"i
90
+ persist_partition_clause: "by"i column_list
91
+
92
+ // short persist with auto query
93
+ auto_persist: PERSIST_MODE IDENTIFIER where?
94
+
95
+ // full persist with query
96
+ full_persist: PERSIST_MODE IDENTIFIER? "into"i IDENTIFIER persist_partition_clause? "from"i select_statement
97
+
98
+ persist_statement: auto_persist | full_persist
99
+
100
+ // select statement
101
+ select_statement: where? "select"i select_list where? having? order_by? limit?
102
+
103
+ // multiple_selects
104
+ multi_select_statement: select_statement ("merge" select_statement)+ "align"i align_clause ("derive" derive_clause)? where? order_by? limit?
105
+
106
+ align_item: IDENTIFIER ":" IDENTIFIER ("," IDENTIFIER)* ","?
107
+
108
+ align_clause: align_item ("AND"i align_item)* "AND"i?
109
+
110
+ derive_item: expr "->" IDENTIFIER
111
+
112
+ derive_clause: derive_item ("," derive_item)* ","?
113
+
114
+ merge_statement: "merge"i WILDCARD_IDENTIFIER "into"i SHORTHAND_MODIFIER? WILDCARD_IDENTIFIER
115
+
116
+ // raw sql statement
117
+ rawsql_statement: "raw_sql"i "(" MULTILINE_STRING ")"
118
+
119
+ // validate_statement
120
+
121
+ VALIDATE_SCOPE: "concepts"i | "datasources"i | "datasource"i | "concept"i
122
+
123
+ validate_statement: ("validate"i "all"i) | ( "validate"i VALIDATE_SCOPE (IDENTIFIER ("," IDENTIFIER)* ","? )? )
124
+
125
+ // mock statement
126
+
127
+ mock_statement: "mock"i VALIDATE_SCOPE (IDENTIFIER ("," IDENTIFIER)* ","? )?
128
+
129
+ // publish statement
130
+ PUBLISH_ACTION : "publish"i | "unpublish"i
131
+ publish_statement: PUBLISH_ACTION VALIDATE_SCOPE IDENTIFIER
132
+
133
+ // create_statement
134
+ CREATE_IF_NOT_EXISTS: /if\s+not\s+exists/i
135
+ CREATE_OR_REPLACE: /or\s+replace/i
136
+
137
+ create_modifier_clause: CREATE_IF_NOT_EXISTS | CREATE_OR_REPLACE
138
+ create_statement: "create"i create_modifier_clause? VALIDATE_SCOPE IDENTIFIER
139
+
140
+ // copy statement
141
+
142
+ COPY_TYPE: "csv"i | "parquet"i
143
+
144
+ copy_statement: "copy"i "into"i COPY_TYPE string_lit "from"i select_statement
145
+
146
+ // FUNCTION blocks
147
+ function: raw_function
148
+ function_binding_type: ":" data_type
149
+ function_binding_default: /=/ expr
150
+ function_binding_item: IDENTIFIER function_binding_type? function_binding_default?
151
+ function_binding_list: (function_binding_item ",")* function_binding_item ","?
152
+ raw_function: "def" IDENTIFIER "(" function_binding_list ")" "->" expr
153
+
154
+ // TYPE blocks
155
+ type_drop_clause: "DROP" IDENTIFIER ("|" IDENTIFIER)*
156
+ //type_add_clause: "ADD" IDENTIFIER ("|" IDENTIFIER)* type_add_clause?
157
+ type_declaration: "type" IDENTIFIER data_type ("|" data_type)* type_drop_clause?
158
+
159
+ // user_id where state = Mexico
160
+ _filter_alt: (IDENTIFIER | literal | _static_functions | "(" expr ")") "?" conditional
161
+ _filter_base: "filter"i IDENTIFIER where
162
+ filter_item: _filter_base | _filter_alt
163
+
164
+ // rank/lag/lead
165
+ WINDOW_TYPE: ("row_number"i|"rank"i|"lag"i|"lead"i | "sum"i | "avg"i | "max"i | "min"i | "count"i ) /[\s]+/
166
+
167
+ window_item_over: ("OVER"i over_list)
168
+
169
+ window_item_order: ("ORDER"i? "BY"i order_list)
170
+
171
+ window_item: WINDOW_TYPE int_lit? expr window_item_over? window_item_order?
172
+
173
+ select_hide_modifier: "--"
174
+ select_partial_modifier: "~"
175
+ select_item: (select_hide_modifier | select_partial_modifier)? (concept_lit | select_transform )
176
+
177
+ select_list: select_item ("," select_item )* ","?
178
+
179
+ // count(post_id) -> post_count
180
+ _assignment: ("->") | "as"i
181
+ select_transform : expr _assignment IDENTIFIER metadata?
182
+
183
+ metadata: "metadata" "(" IDENTIFIER "=" string_lit ")"
184
+
185
+ limit: "LIMIT"i /[0-9]+/
186
+
187
+ ORDER_IDENTIFIER.2: /(?!LIMIT)[a-zA-Z_][a-zA-Z0-9_\.]*\s+/
188
+ _order_atom: (ORDER_IDENTIFIER ordering) | (expr ordering)
189
+
190
+ order_list: _order_atom ("," _order_atom)* ","?
191
+
192
+ over_component: /,\s*[a-zA-Z\_][a-zA-Z0-9\_\.]*/ "END"?
193
+
194
+ over_list: concept_lit over_component*
195
+
196
+ ORDERING_DIRECTION: /ASC|DESC/i
197
+
198
+ !ordering: ORDERING_DIRECTION ("NULLS"i /FIRST|LAST|AUTO/i )?
199
+
200
+ order_by: "ORDER"i "BY"i order_list
201
+
202
+ //WHERE STATEMENT
203
+ LOGICAL_OR: "or"i
204
+ LOGICAL_AND: "and"i
205
+
206
+ conditional: _or_condition
207
+
208
+ _or_condition: _and_condition
209
+ | (_or_condition LOGICAL_OR _and_condition)
210
+
211
+ _and_condition: _condition_unit
212
+ | (_and_condition LOGICAL_AND _condition_unit)
213
+
214
+ CONDITION_NOT: "NOT"i
215
+ condition_parenthetical: CONDITION_NOT? "(" conditional ")"
216
+
217
+ _condition_unit: expr
218
+ | condition_parenthetical
219
+
220
+ where: "WHERE"i conditional
221
+
222
+ having: "HAVING"i conditional
223
+
224
+ !array_comparison: ( ("NOT"i "IN"i) | "IN"i)
225
+
226
+ COMPARISON_OPERATOR: /(\s+is\s+not\s|\s+is\s|\s+in\s|\s+not\s+in\s|=|>=|<=|!=|>|<)/i
227
+
228
+ between_comparison: "between"i expr "and"i expr
229
+
230
+ subselect_comparison: expr array_comparison (literal | _constant_functions | _string_functions | _array_functions | concept_lit | filter_item | window_item | unnest | fgroup | expr_tuple | parenthetical )
231
+
232
+ expr_tuple: ("(" expr ("," expr)+ ","? ")") | ("(" expr "," ")")
233
+
234
+ parenthetical: "(" expr ")"
235
+
236
+ //unnesting is a function
237
+ _UNNEST.1: "UNNEST("i
238
+ unnest: _UNNEST expr ")"
239
+
240
+ // union statement
241
+ _UNION.1: "UNION("i
242
+ union: _UNION (expr ",")* expr ")"
243
+
244
+ //indexing into an expression is a function
245
+ index_access: atom "[" int_lit "]"
246
+ map_key_access: atom "[" string_lit "]"
247
+ _ATTR_ACCESS.1 : "getattr("i
248
+ attr_access: ( _ATTR_ACCESS atom "," string_lit ")") | (atom "." string_lit)
249
+
250
+ ?expr: comparison_root | between_root
251
+
252
+ ?comparison_root: sum_chain (COMPARISON_OPERATOR sum_chain)? -> comparison
253
+ ?between_root: sum_chain "between"i sum_chain "and"i sum_chain -> between_comparison
254
+
255
+ PLUS_OR_MINUS: ("+" | /-(?!>)/ | "||" | "like" )
256
+
257
+ ?sum_chain: product_chain (PLUS_OR_MINUS product_chain)* -> sum_operator
258
+
259
+ MULTIPLY_DIVIDE_PERCENT: ("**" | "*" | "/" | "%")
260
+
261
+ ?product_chain: atom ( MULTIPLY_DIVIDE_PERCENT atom)* -> product_operator
262
+
263
+ ?atom: literal | concept_lit | parenthetical
264
+ | expr_tuple
265
+ | custom_function
266
+ | _constant_functions
267
+ | _static_functions
268
+ | _generic_functions
269
+ | _date_functions
270
+ | aggregate_functions
271
+ | window_item
272
+ | unnest
273
+ | union
274
+ | fgroup
275
+ | filter_item
276
+ | _access_expr
277
+ | aggregate_by
278
+
279
+
280
+ # Access patterns
281
+ _access_expr: index_access | map_key_access | attr_access
282
+ // functions
283
+
284
+ fadd: (/add\(/ expr "," expr ")" )
285
+ fsub: ("subtract"i "(" expr "," expr ")" )
286
+ fmul: ("multiply"i "(" expr "," expr ")" )
287
+ fdiv: ( "divide"i "(" expr "," expr ")")
288
+ fmod: ( "mod"i "(" expr "," (int_lit | concept_lit ) ")")
289
+ _LOG.1: "log"i "("
290
+ flog: _LOG expr ("," expr)? ")"
291
+ _ROUND.1: "round"i "("
292
+ fround: _ROUND expr ("," expr)? ")"
293
+ _FLOOR.1: "floor"i "("
294
+ ffloor: _FLOOR expr ")"
295
+ _CEIL.1: "ceil"i "("
296
+ fceil: _CEIL expr ")"
297
+ fabs: "abs"i "(" expr ")"
298
+ _SQRT.1: "sqrt("
299
+ fsqrt: _SQRT expr ")"
300
+ _RANDOM.1: "random("i
301
+ frandom: _RANDOM expr ")"
302
+
303
+ _math_functions: fmul | fdiv | fadd | fsub | fround | ffloor | fceil | fmod | flog | fabs | fsqrt | frandom
304
+
305
+ //generic
306
+ _fcast_primary: "cast"i "(" expr "as"i data_type ")"
307
+ _fcast_alt: atom "::" data_type
308
+ fcast: _fcast_primary | _fcast_alt
309
+ concat: ("concat"i "(" (expr ",")* expr ")")
310
+ fcoalesce: "coalesce"i "(" (expr ",")* expr ")"
311
+ fcase_when: "WHEN"i conditional "THEN"i expr
312
+ fcase_else: "ELSE"i expr
313
+ fcase: "CASE"i (fcase_when)* (fcase_else)? "END"i
314
+ len: "len"i "(" expr ")"
315
+ fnot: "NOT"i expr
316
+ fbool: "bool"i "(" expr ")"
317
+ fnullif: "nullif"i "(" expr "," expr ")"
318
+ _FRECURSE_EDGE.1: "recurse_edge("i
319
+ frecurse_edge: _FRECURSE_EDGE expr "," expr ")"
320
+
321
+ _generic_functions: fcast | concat | fcoalesce | fnullif | fcase | len | fnot | fbool | frecurse_edge
322
+
323
+ //constant
324
+ CURRENT_DATE.1: /current_date\(\)/
325
+ CURRENT_DATETIME.1: /current_datetime\(\)/
326
+ CURRENT_TIMESTAMP.1: /current_timestamp\(\)/
327
+ fcurrent_date: CURRENT_DATE
328
+ fcurrent_datetime: CURRENT_DATETIME
329
+ fcurrent_timestamp: CURRENT_TIMESTAMP
330
+
331
+ _constant_functions: fcurrent_date | fcurrent_datetime | fcurrent_timestamp
332
+
333
+ //string
334
+ _LIKE.1: "like("i
335
+ like: _LIKE expr "," string_lit ")"
336
+ _ILIKE.1: "ilike("i
337
+ ilike: _ILIKE expr "," string_lit ")"
338
+ alt_like: expr "like"i expr
339
+ _UPPER.1: "upper("i
340
+ upper: _UPPER expr ")"
341
+ _LOWER.1: "lower("i
342
+ flower: _LOWER expr ")"
343
+ _SPLIT.1: "split("i
344
+ fsplit: _SPLIT expr "," string_lit ")"
345
+ _STRPOS.1: "strpos("i
346
+ fstrpos: _STRPOS expr "," expr ")"
347
+ _CONTAINS.1: "contains("i
348
+ fcontains: _CONTAINS expr "," expr ")"
349
+ _TRIM.1: "trim("i
350
+ ftrim: _TRIM expr ")"
351
+ _REPLACE.1: "replace("i
352
+ freplace: _REPLACE expr "," expr "," expr ")"
353
+ _SUBSTRING.1: "substring("i
354
+ fsubstring: _SUBSTRING expr "," expr "," expr ")"
355
+ _REGEXP_EXTRACT.1: "regexp_extract("
356
+ fregexp_extract: _REGEXP_EXTRACT expr "," expr ("," int_lit)? ")"
357
+ _REGEXP_CONTAINS.1: "regexp_contains("
358
+ fregexp_contains: _REGEXP_CONTAINS expr "," expr ")"
359
+ _REGEXP_REPLACE.1: "regexp_replace("
360
+ fregexp_replace: _REGEXP_REPLACE expr "," expr "," expr ")"
361
+ _HASH.1: "hash("
362
+ HASH_TYPE: "md5"i | "sha1"i | "sha256"i | "sha512"i
363
+ fhash: _HASH expr "," HASH_TYPE ")"
364
+
365
+ _string_functions: like | ilike | upper | flower | fsplit | fstrpos | fsubstring | fcontains | ftrim | freplace | fregexp_extract | fregexp_contains | fregexp_replace | fhash
366
+
367
+ //array_functions
368
+ _ARRAY_SUM.1: "array_sum("i
369
+ farray_sum: _ARRAY_SUM expr ")"
370
+ _ARRAY_DISTINCT.1: "array_distinct("i
371
+ farray_distinct: _ARRAY_DISTINCT expr ")"
372
+ _ARRAY_TO_STRING.1: "array_to_string("i
373
+ farray_to_string: _ARRAY_TO_STRING expr "," expr ")"
374
+ _ARRAY_SORT.1: "array_sort("i
375
+ farray_sort: _ARRAY_SORT expr ("," ordering )? ")"
376
+ _ARRAY_TRANSFORM.1: "array_transform("i
377
+ transform_lambda: "@" IDENTIFIER
378
+ farray_transform: _ARRAY_TRANSFORM expr "," transform_lambda ")"
379
+ _ARRAY_FILTER.1: "array_filter("i
380
+ farray_filter: _ARRAY_FILTER expr "," transform_lambda ")"
381
+ _GENERATE_ARRAY.1: "generate_array("i
382
+ fgenerate_array: _GENERATE_ARRAY expr "," expr "," expr ")"
383
+
384
+ _array_functions: farray_sum | farray_distinct | farray_sort | farray_transform | farray_to_string | farray_filter | fgenerate_array
385
+
386
+ //map_functions
387
+ _MAP_KEYS.1: "map_keys("i
388
+ fmap_keys: _MAP_KEYS expr ")"
389
+ _MAP_VALUES.1: "map_values("i
390
+ fmap_values: _MAP_VALUES expr ")"
391
+
392
+ _map_functions: fmap_keys | fmap_values
393
+
394
+ // special aggregate
395
+ _GROUP.1: "group("i
396
+ fgroup: _GROUP expr ")" aggregate_over?
397
+
398
+ //by:
399
+ aggregate_by: /(group)\s+([a-zA-Z\_][a-zA-Z0-9\_\.]*)/i "BY"i (IDENTIFIER ",")* IDENTIFIER
400
+
401
+ //aggregates
402
+ _COUNT.1: "count("i
403
+ count: _COUNT expr ")"
404
+
405
+ count_distinct: "count_distinct"i "(" expr ")"
406
+
407
+ // avoid conflicts with the window
408
+ _SUM.1: "sum("i
409
+ sum: _SUM expr ")"
410
+ _AVG.1: "avg("i
411
+ avg: _AVG expr ")"
412
+ _MAX.1: "max("i
413
+ max: _MAX expr ")"
414
+ _MIN.1: "min("i
415
+ min: _MIN expr ")"
416
+ _ARRAY_AGG.1: "array_agg("i
417
+ array_agg: _ARRAY_AGG expr ")"
418
+ _BOOL_OR.1: "bool_or("i
419
+ bool_or: _BOOL_OR expr ")"
420
+ _BOOL_AND.1: "bool_and("i
421
+ bool_and: _BOOL_AND expr ")"
422
+ _ANY.1: "any("i
423
+ any: _ANY expr ")"
424
+
425
+ //aggregates can force a grain
426
+ aggregate_all: "*"
427
+ aggregate_over: ("BY"i (aggregate_all | over_list))
428
+ aggregate_functions: (count | count_distinct | sum | avg | max | min | array_agg | bool_and | bool_or | any) aggregate_over?
429
+
430
+ // date functions
431
+ _DATE.1: "date("i
432
+ fdate: _DATE expr ")"
433
+ fdatetime: "datetime"i "(" expr ")"
434
+ _TIMESTAMP.1: "timestamp("i
435
+ ftimestamp: _TIMESTAMP expr ")"
436
+
437
+ _SECOND.1: "second("i
438
+ fsecond: _SECOND expr ")"
439
+ _MINUTE.1: "minute("i
440
+ fminute: _MINUTE expr ")"
441
+ _HOUR.1: "hour("i
442
+ fhour: _HOUR expr ")"
443
+ _DAY.1: "day("i
444
+ fday: _DAY expr ")"
445
+ _DAY_NAME.1: "day_name("i
446
+ fday_name: _DAY_NAME expr ")"
447
+ _DAY_OF_WEEK.1: "day_of_week("i
448
+ fday_of_week: _DAY_OF_WEEK expr ")"
449
+ _WEEK.1: "week("i
450
+ fweek: _WEEK expr ")"
451
+ _MONTH.1: "month("i
452
+ fmonth: _MONTH expr ")"
453
+ _MONTH_NAME.1: "month_name("i
454
+ fmonth_name: _MONTH_NAME expr ")"
455
+ _QUARTER.1: "quarter("i
456
+ fquarter: _QUARTER expr ")"
457
+ _YEAR.1: "year("i
458
+ fyear: _YEAR expr ")"
459
+
460
+ DATE_PART: "DAY"i | "WEEK"i | "MONTH"i | "QUARTER"i | "YEAR"i | "MINUTE"i | "HOUR"i | "SECOND"i | "DAY_OF_WEEK"i
461
+ _DATE_TRUNC.1: "date_trunc("i | "date_truncate("i
462
+ fdate_trunc: _DATE_TRUNC expr "," DATE_PART ")"
463
+ _DATE_PART.1: "date_part("i
464
+ fdate_part: _DATE_PART expr "," DATE_PART ")"
465
+ _DATE_ADD.1: "date_add("i
466
+ fdate_add: _DATE_ADD expr "," DATE_PART "," expr ")"
467
+ _DATE_SUB.1: "date_sub("i
468
+ fdate_sub: _DATE_SUB expr "," DATE_PART "," expr ")"
469
+ _DATE_DIFF.1: "date_diff("i
470
+ fdate_diff: _DATE_DIFF expr "," expr "," DATE_PART ")"
471
+ _DATE_SPINE.1: "date_spine("i
472
+ fdate_spine: _DATE_SPINE expr "," expr ")"
473
+
474
+ _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
475
+
476
+ _static_functions: _string_functions | _math_functions | _array_functions | _map_functions
477
+
478
+ custom_function: "@" IDENTIFIER "(" (expr ",")* expr ")"
479
+
480
+ // base language constructs
481
+ concept_lit: IDENTIFIER
482
+ IDENTIFIER: /[a-zA-Z\_][a-zA-Z0-9\_\.]*/
483
+ WILDCARD_IDENTIFIER: /[a-zA-Z\_][a-zA-Z0-9\_\-\.\*]*/
484
+ QUOTED_IDENTIFIER: /`[a-zA-Z\_][a-zA-Z0-9\_\.\-\*\:\s]*`/
485
+ QUOTED_ADDRESS: /`'?[a-zA-Z\_\\\/][a-zA-Z0-9\_\.\\\/\-\*\:\s]*'?`/
486
+ ADDRESS: IDENTIFIER
487
+
488
+ MULTILINE_STRING: /\'{3}(.*?)\'{3}/s
489
+ FILE_PATH: /`[^`]+\.(py|csv|parquet|tsv|sql)`/i
490
+
491
+ DOUBLE_STRING_CHARS: /(?:(?!\${)([^"\\]|\\.))+/+ // any character except "
492
+ SINGLE_STRING_CHARS: /(?:(?!\${)([^'\\]|\\.))+/+ // any character except '
493
+ _single_quote: "'" ( SINGLE_STRING_CHARS )* "'"
494
+ _double_quote: "\"" ( DOUBLE_STRING_CHARS )* "\""
495
+ string_lit: _single_quote | _double_quote | MULTILINE_STRING
496
+
497
+
498
+
499
+ int_lit: /\-?[0-9]+/
500
+
501
+ float_lit: /\-?[0-9]*\.[0-9]+/
502
+
503
+ array_lit: "[" (expr ",")* expr ","? "]"()
504
+
505
+ tuple_lit: "(" (literal ",")* literal ","? ")"
506
+
507
+ map_lit: "{" (literal ":" literal ",")* literal ":" literal ","? "}"
508
+
509
+ _STRUCT.1: "struct("i
510
+ _BINDING.1: "->"
511
+ struct_lit: _STRUCT expr _BINDING IDENTIFIER ( "," expr _BINDING IDENTIFIER )* ","? ")"
512
+
513
+ !bool_lit: "True"i | "False"i
514
+
515
+ !null_lit.1: "null"i
516
+
517
+ literal: null_lit | string_lit | int_lit | float_lit | bool_lit | array_lit | map_lit | struct_lit | tuple_lit
518
+
519
+ MODIFIER: /OPTIONAL|PARTIAL|NULLABLE/i
520
+
521
+ SHORTHAND_MODIFIER: /~|\?/
522
+ struct_component: IDENTIFIER ":" data_type concept_nullable_modifier? metadata?
523
+ struct_type: "struct"i "<" ((struct_component | IDENTIFIER) ",")* (struct_component | IDENTIFIER) ","? ">"
524
+
525
+ list_type: ("list"i | "array"i) "<" (data_type | IDENTIFIER) ">"
526
+
527
+ numeric_type: "numeric"i "(" int_lit "," int_lit ")"
528
+
529
+ map_type: "map"i "<" (data_type | IDENTIFIER) "," (data_type | IDENTIFIER) ">"
530
+
531
+ !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)?
532
+
533
+ PURPOSE: "key"i | "metric"i | "parameter"i | "param"i | CONST
534
+ PROPERTY: "property"i
535
+ CONST: "const"i | "constant"i
536
+ AUTO: "AUTO"i
537
+ // meta functions
538
+ CONCEPTS: "CONCEPTS"i
539
+ DATASOURCES: "DATASOURCES"i
540
+ show_category: CONCEPTS | DATASOURCES
541
+
542
+ show_statement: "show"i ( show_category | validate_statement | select_statement | persist_statement) _TERMINATOR
543
+ COMMENT: /#.*(\n|$)/ | /\/\/.*\n/
544
+ %import common.WS
545
+ %ignore WS
546
+ %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
+ )