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