pytrilogy 0.0.3.93__py3-none-any.whl → 0.0.3.95__py3-none-any.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.

Potentially problematic release.


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

Files changed (39) hide show
  1. {pytrilogy-0.0.3.93.dist-info → pytrilogy-0.0.3.95.dist-info}/METADATA +170 -145
  2. {pytrilogy-0.0.3.93.dist-info → pytrilogy-0.0.3.95.dist-info}/RECORD +38 -34
  3. trilogy/__init__.py +1 -1
  4. trilogy/authoring/__init__.py +4 -0
  5. trilogy/core/enums.py +13 -0
  6. trilogy/core/env_processor.py +21 -10
  7. trilogy/core/environment_helpers.py +111 -0
  8. trilogy/core/exceptions.py +21 -1
  9. trilogy/core/functions.py +6 -1
  10. trilogy/core/graph_models.py +60 -67
  11. trilogy/core/internal.py +18 -0
  12. trilogy/core/models/author.py +16 -25
  13. trilogy/core/models/build.py +5 -4
  14. trilogy/core/models/core.py +3 -0
  15. trilogy/core/models/environment.py +28 -0
  16. trilogy/core/models/execute.py +7 -0
  17. trilogy/core/processing/node_generators/node_merge_node.py +30 -28
  18. trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +25 -11
  19. trilogy/core/processing/node_generators/select_merge_node.py +68 -82
  20. trilogy/core/query_processor.py +2 -1
  21. trilogy/core/statements/author.py +18 -3
  22. trilogy/core/statements/common.py +0 -10
  23. trilogy/core/statements/execute.py +71 -16
  24. trilogy/core/validation/__init__.py +0 -0
  25. trilogy/core/validation/common.py +109 -0
  26. trilogy/core/validation/concept.py +122 -0
  27. trilogy/core/validation/datasource.py +192 -0
  28. trilogy/core/validation/environment.py +71 -0
  29. trilogy/dialect/base.py +40 -21
  30. trilogy/dialect/sql_server.py +3 -1
  31. trilogy/engine.py +25 -7
  32. trilogy/executor.py +145 -83
  33. trilogy/parsing/parse_engine.py +35 -4
  34. trilogy/parsing/trilogy.lark +11 -5
  35. trilogy/core/processing/node_generators/select_merge_node_v2.py +0 -792
  36. {pytrilogy-0.0.3.93.dist-info → pytrilogy-0.0.3.95.dist-info}/WHEEL +0 -0
  37. {pytrilogy-0.0.3.93.dist-info → pytrilogy-0.0.3.95.dist-info}/entry_points.txt +0 -0
  38. {pytrilogy-0.0.3.93.dist-info → pytrilogy-0.0.3.95.dist-info}/licenses/LICENSE.md +0 -0
  39. {pytrilogy-0.0.3.93.dist-info → pytrilogy-0.0.3.95.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytrilogy
3
- Version: 0.0.3.93
3
+ Version: 0.0.3.95
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -36,32 +36,64 @@ Dynamic: provides-extra
36
36
  Dynamic: requires-dist
37
37
  Dynamic: summary
38
38
 
39
- ## Trilogy
39
+ # Trilogy
40
+ **SQL with superpowers for analytics**
41
+
40
42
  [![Website](https://img.shields.io/badge/INTRO-WEB-orange?)](https://trilogydata.dev/)
41
43
  [![Discord](https://img.shields.io/badge/DISCORD-CHAT-red?logo=discord)](https://discord.gg/Z4QSSuqGEd)
44
+ [![PyPI version](https://badge.fury.io/py/pytrilogy.svg)](https://badge.fury.io/py/pytrilogy)
42
45
 
43
- The Trilogy language is an experiment in better SQL for analytics - a streamlined SQL that replaces tables/joins with a lightweight semantic binding layer and provides easy reuse and composability. It compiles to SQL - making it easy to debug or integrate into existing workflows - and can be run against any supported SQL backend.
46
+ The Trilogy language is an experiment in better SQL for analytics - a streamlined SQL that replaces tables/joins with a lightweight semantic binding layer and provides easy reuse and composability. It compiles to SQL - making it easy to debug or integrate into existing workflows - and can be run against any supported SQL backend.
44
47
 
45
48
  [pytrilogy](https://github.com/trilogy-data/pytrilogy) is the reference implementation, written in Python.
46
49
 
47
- ### What Trilogy Gives You
50
+ ## What Trilogy Gives You
51
+
52
+ - **Speed** - write faster, with concise, powerful syntax
53
+ - **Efficiency** - write less SQL, and reuse what you do
54
+ - **Fearless refactoring** - change models without breaking queries
55
+ - **Testability** - built-in testing patterns with query fixtures
56
+ - **Easy to use** - for humans and LLMs alike
48
57
 
49
- - Speed - write faster, with concise, powerful syntax
50
- - Efficiency - write less SQL, and reuse what you do
51
- - Fearless refactoring
52
- - Testability
53
- - Easy to use for humans and LLMs
58
+ Trilogy is especially powerful for data consumption, providing a rich metadata layer that makes creating, interpreting, and visualizing queries easy and expressive.
54
59
 
55
- Trilogy is especially powerful for data consumption, providing a rich metadata layer that makes creating, interperting, and visualizing queries easy and expressive.
60
+ ## Quick Start
56
61
 
57
62
  > [!TIP]
58
- > You can try Trilogy in a [open-source studio](https://trilogydata.dev/trilogy-studio-core/). More details on the language can be found on the [documentation](https://trilogydata.dev/).
63
+ > **Try it now:** [Open-source studio](https://trilogydata.dev/trilogy-studio-core/) | [Interactive demo](https://trilogydata.dev/demo/) | [Documentation](https://trilogydata.dev/)
59
64
 
60
- We recommend starting with the studio to explore Trilogy. For integration, `pytrilogy` can be run locally to parse and execute trilogy model [.preql] files using the `trilogy` CLI tool, or can be run in python by importing the `trilogy` package.
65
+ **Install locally:**
66
+ ```bash
67
+ pip install pytrilogy
68
+ ```
69
+
70
+ **Your first query:**
71
+ ```sql
72
+ # Save as hello.preql
73
+ import names;
74
+
75
+ const top_names <- ['Elvis', 'Elvira', 'Elrond', 'Sam'];
76
+
77
+ def initcap(word) -> upper(substring(word, 1, 1)) || substring(word, 2, len(word));
78
+
79
+ WHERE
80
+ @initcap(name) in top_names
81
+ SELECT
82
+ name,
83
+ sum(births) as name_count
84
+ ORDER BY
85
+ name_count desc
86
+ LIMIT 10;
87
+ ```
88
+
89
+ **Run it:**
90
+ ```bash
91
+ trilogy run hello.preql duckdb
92
+ ```
61
93
 
62
- Installation: `pip install pytrilogy`
94
+ We recommend starting with the studio to explore Trilogy. For integration, `pytrilogy` can be run locally to parse and execute trilogy model [.preql] files using the `trilogy` CLI tool, or can be run in python by importing the `trilogy` package.
63
95
 
64
- ### Trilogy Looks Like SQL
96
+ ## Trilogy Looks Like SQL
65
97
 
66
98
  ```sql
67
99
  import names;
@@ -79,26 +111,40 @@ ORDER BY
79
111
  name_count desc
80
112
  LIMIT 10;
81
113
  ```
114
+
82
115
  ## Goals
116
+
83
117
  Versus SQL, Trilogy aims to:
84
118
 
85
- Keep:
119
+ **Keep:**
86
120
  - Correctness
87
121
  - Accessibility
88
122
 
89
- Improve:
123
+ **Improve:**
90
124
  - Simplicity
91
- - Refactoring/mantainability
125
+ - Refactoring/maintainability
92
126
  - Reusability
93
127
 
94
- Maintain:
128
+ **Maintain:**
95
129
  - Acceptable performance
96
130
 
97
- Remove:
131
+ **Remove:**
98
132
  - Lower-level procedural features
99
133
  - Transactional optimizations/non-analytics features
100
134
 
101
- ## Hello World
135
+ ## Backend Support
136
+
137
+ | Backend | Status | Notes |
138
+ |---------|--------|-------|
139
+ | **BigQuery** | ✅ Core | Full support |
140
+ | **DuckDB** | ✅ Core | Full support |
141
+ | **Snowflake** | ✅ Core | Full support |
142
+ | **SQL Server** | ⚠️ Experimental | Limited testing |
143
+ | **Presto** | ⚠️ Experimental | Limited testing |
144
+
145
+ ## Examples
146
+
147
+ ### Hello World
102
148
 
103
149
  Save the following code in a file named `hello.preql`
104
150
 
@@ -161,50 +207,33 @@ WHERE
161
207
  SELECT
162
208
  sentences.text
163
209
  ;
164
-
165
210
  ```
166
- Run the following from the directory the file is in.
167
211
 
212
+ **Run it:**
168
213
  ```bash
169
- trilogy run hello.trilogy duckdb
214
+ trilogy run hello.preql duckdb
170
215
  ```
171
216
 
172
217
  ![UI Preview](hello-world.png)
173
218
 
174
- ## Backends
175
-
176
- The current Trilogy implementation supports these backends:
177
-
178
- ### Core
179
- - Bigquery
180
- - DuckDB
181
- - Snowflake
182
-
183
- ### Experimental
184
- - SQL Server
185
- - Presto
186
-
187
- ## Basic Example - Python
219
+ ### Python SDK Usage
188
220
 
189
221
  Trilogy can be run directly in python through the core SDK. Trilogy code can be defined and parsed inline or parsed out of files.
190
222
 
191
- A bigquery example, similar to bigquery [the quickstart](https://cloud.google.com/bigquery/docs/quickstarts/query-public-dataset-console).
223
+ A BigQuery example, similar to the [BigQuery quickstart](https://cloud.google.com/bigquery/docs/quickstarts/query-public-dataset-console):
192
224
 
193
225
  ```python
194
-
195
226
  from trilogy import Dialects, Environment
196
227
 
197
228
  environment = Environment()
198
229
 
199
230
  environment.parse('''
200
-
201
231
  key name string;
202
232
  key gender string;
203
233
  key state string;
204
234
  key year int;
205
235
  key yearly_name_count int; int;
206
236
 
207
-
208
237
  datasource usa_names(
209
238
  name:name,
210
239
  number:yearly_name_count,
@@ -213,13 +242,11 @@ datasource usa_names(
213
242
  state:state
214
243
  )
215
244
  address `bigquery-public-data.usa_names.usa_1910_2013`;
245
+ ''')
216
246
 
217
- '''
218
- )
219
247
  executor = Dialects.BIGQUERY.default_executor(environment=environment)
220
248
 
221
- results = executor.execute_text(
222
- '''
249
+ results = executor.execute_text('''
223
250
  WHERE
224
251
  name = 'Elvis'
225
252
  SELECT
@@ -228,9 +255,8 @@ SELECT
228
255
  ORDER BY
229
256
  name_count desc
230
257
  LIMIT 10;
231
- '''
258
+ ''')
232
259
 
233
- )
234
260
  # multiple queries can result from one text batch
235
261
  for row in results:
236
262
  # get results for first query
@@ -239,105 +265,90 @@ for row in results:
239
265
  print(x)
240
266
  ```
241
267
 
242
-
243
- ## Basic Example - CLI
268
+ ### CLI Usage
244
269
 
245
270
  Trilogy can be run through a CLI tool, also named 'trilogy'.
246
271
 
247
- After installing trilogy, you can run the trilogy CLI with two required positional arguments; the first the path to a file or a direct command,
248
- and second the dialect to run.
249
-
250
- `trilogy run <cmd or path to trilogy file> <dialect>`
251
-
252
- To pass arguments to a backend, append additional --<option> flags after specifying the dialect.
253
-
254
- Example:
255
- `trilogy run "key x int; datasource test_source ( i:x) grain(in) address test; select x;" duckdb --path <path/to/database>`
256
-
257
- ### Bigquery Args
258
- N/A, only supports default auth. In python you can pass in a custom client.
259
- <TODO> support arbitrary cred paths.
260
-
261
- ### DuckDB Args
262
- - path <optional>
263
-
264
- ### Postgres Args
265
- - host
266
- - port
267
- - username
268
- - password
269
- - database
270
-
271
- ### Snowflake Args
272
- - account
273
- - username
274
- - password
275
-
276
-
277
- > [!TIP]
278
- > The CLI can also be used for formatting. Trilogy has a default formatting style that should always be adhered to. `trilogy fmt <path to trilogy file>`
279
-
280
-
281
- ## More Examples
282
-
283
- [Interactive demo](https://trilogydata.dev/demo/).
284
-
285
- Additional examples can be found in the [public model repository](https://github.com/trilogydata/trilogy-public-models).
286
-
287
- This is a good place to look for modeling examples.
288
-
289
- ## Developing
272
+ **Basic syntax:**
273
+ ```bash
274
+ trilogy run <cmd or path to trilogy file> <dialect>
275
+ ```
290
276
 
291
- Clone repository and install requirements.txt and requirements-test.txt.
277
+ **With backend options:**
278
+ ```bash
279
+ trilogy run "key x int; datasource test_source(i:x) grain(x) address test; select x;" duckdb --path <path/to/database>
280
+ ```
292
281
 
293
- ## Contributing
282
+ **Format code:**
283
+ ```bash
284
+ trilogy fmt <path to trilogy file>
285
+ ```
294
286
 
295
- Please open an issue first to discuss what you would like to change, and then create a PR against that issue.
287
+ #### Backend Configuration
296
288
 
297
- ## Similar in space
298
- Trilogy combines two aspects; a semantic layer and a query language. Examples of both are linked below:
289
+ **BigQuery:**
290
+ - Uses applicationdefault authentication (TODO: support arbitrary credential paths)
291
+ - In Python, you can pass a custom client
299
292
 
300
- "semantic layers" are tools for defining an metadata layer above a SQL/warehouse base to enable higher level abstractions.
293
+ **DuckDB:**
294
+ - `--path` - Optional database file path
301
295
 
302
- - [metricsflow](https://github.com/dbt-labs/metricflow)
303
- - [cube](https://github.com/cube-js/cube)
304
- - [zillion](https://github.com/totalhack/zillion)
296
+ **Postgres:**
297
+ - `--host` - Database host
298
+ - `--port` - Database port
299
+ - `--username` - Username
300
+ - `--password` - Password
301
+ - `--database` - Database name
305
302
 
306
- "Better SQL" has been a popular space. We believe Trilogy takes a different approach then the following,
307
- but all are worth checking out. Please open PRs/comment for anything missed!
303
+ **Snowflake:**
304
+ - `--account` - Snowflake account
305
+ - `--username` - Username
306
+ - `--password` - Password
308
307
 
309
- - [malloy](https://github.com/malloydata/malloy)
310
- - [preql](https://github.com/erezsh/Preql)
311
- - [PREQL](https://github.com/PRQL/prql)
308
+ ## More Resources
312
309
 
313
- ## Minimal Syntax Reference
310
+ - [Interactive demo](https://trilogydata.dev/demo/)
311
+ - [Public model repository](https://github.com/trilogydata/trilogy-public-models) - Great place for modeling examples
312
+ - [Full documentation](https://trilogydata.dev/)
314
313
 
315
- #### IMPORT
314
+ ## Syntax Reference
316
315
 
317
- `import [path] as [alias];`
316
+ ### Import
317
+ ```sql
318
+ import [path] as [alias];
319
+ ```
318
320
 
319
- #### CONCEPT
321
+ ### Concepts
320
322
 
321
- Types: `string | int | float | bool | date | datetime | time | numeric(scale, precision) | timestamp | interval | list<[type]> | map<[type], [type]> | struct<name:[type], name:[type]>`;
323
+ **Types:**
324
+ `string | int | float | bool | date | datetime | time | numeric(scale, precision) | timestamp | interval | array<[type]> | map<[type], [type]> | struct<name:[type], name:[type]>`
322
325
 
323
- Key:
324
- `key [name] [type];`
326
+ **Key:**
327
+ ```sql
328
+ key [name] [type];
329
+ ```
325
330
 
326
- Property:
327
- `property [key>].[name] [type];`
328
- `property x.y int;`
329
- or
330
- `property <[key](,[key])?>.<name> [type];`
331
- `property <x,y>.z int;`
331
+ **Property:**
332
+ ```sql
333
+ property [key].[name] [type];
334
+ property x.y int;
332
335
 
336
+ # or multi-key
337
+ property <[key],[key]>.[name] [type];
338
+ property <x,y>.z int;
339
+ ```
333
340
 
334
- Transformation:
335
- `auto [name] <- [expression];`
336
- `auto x <- y + 1;`
341
+ **Transformation:**
342
+ ```sql
343
+ auto [name] <- [expression];
344
+ auto x <- y + 1;
345
+ ```
337
346
 
338
- #### DATASOURCE
347
+ ### Datasource
339
348
  ```sql
340
349
  datasource <name>(
350
+ <column_and_concept_with_same_name>,
351
+ # or a mapping from column to concept
341
352
  <column>:<concept>,
342
353
  <column>:<concept>,
343
354
  )
@@ -345,14 +356,13 @@ grain(<concept>, <concept>)
345
356
  address <table>;
346
357
  ```
347
358
 
348
- #### SELECT
349
-
350
- Primary acces
359
+ ### Queries
351
360
 
361
+ **Basic SELECT:**
352
362
  ```sql
353
363
  WHERE
354
364
  <concept> = <value>
355
- select
365
+ SELECT
356
366
  <concept>,
357
367
  <concept>+1 -> <alias>,
358
368
  ...
@@ -363,10 +373,7 @@ ORDER BY
363
373
  ;
364
374
  ```
365
375
 
366
- #### CTE/ROWSET
367
-
368
- Reusable virtual set of rows. Useful for windows, filtering.
369
-
376
+ **CTEs/Rowsets:**
370
377
  ```sql
371
378
  with <alias> as
372
379
  WHERE
@@ -376,25 +383,18 @@ select
376
383
  <concept>+1 -> <alias>,
377
384
  ...
378
385
 
379
-
380
386
  select <alias>.<concept>;
381
-
382
387
  ```
383
388
 
389
+ ### Data Operations
384
390
 
385
- #### PERSIST
386
-
387
- Store output of a query in a warehouse table
388
-
391
+ **Persist to table:**
389
392
  ```sql
390
393
  persist <alias> as <table_name> from
391
394
  <select>;
392
395
  ```
393
396
 
394
- #### COPY
395
-
396
- Currently supported target types are <CSV>, though backend support may vary.
397
-
397
+ **Export to file:**
398
398
  ```sql
399
399
  COPY INTO <TARGET_TYPE> '<target_path>' FROM SELECT
400
400
  <concept>, ...
@@ -403,10 +403,35 @@ ORDER BY
403
403
  ;
404
404
  ```
405
405
 
406
- #### SHOW
407
-
408
- Return generated SQL without executing.
409
-
406
+ **Show generated SQL:**
410
407
  ```sql
411
408
  show <select>;
412
409
  ```
410
+
411
+ **Validate Model**
412
+ ```sql
413
+ validate all
414
+ validate concepts abc,def...
415
+ validate datasources abc,def...
416
+ ```
417
+
418
+
419
+ ## Contributing
420
+
421
+ Clone repository and install requirements.txt and requirements-test.txt.
422
+
423
+ Please open an issue first to discuss what you would like to change, and then create a PR against that issue.
424
+
425
+ ## Similar Projects
426
+
427
+ Trilogy combines two aspects: a semantic layer and a query language. Examples of both are linked below:
428
+
429
+ **Semantic layers** - tools for defining a metadata layer above SQL/warehouse to enable higher level abstractions:
430
+ - [MetricFlow](https://github.com/dbt-labs/metricflow)
431
+ - [Cube](https://github.com/cube-js/cube)
432
+ - [Zillion](https://github.com/totalhack/zillion)
433
+
434
+ **Better SQL** has been a popular space. We believe Trilogy takes a different approach than the following, but all are worth checking out. Please open PRs/comment for anything missed!
435
+ - [Malloy](https://github.com/malloydata/malloy)
436
+ - [Preql](https://github.com/erezsh/Preql)
437
+ - [PRQL](https://github.com/PRQL/prql)
@@ -1,35 +1,35 @@
1
- pytrilogy-0.0.3.93.dist-info/licenses/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
2
- trilogy/__init__.py,sha256=bRQB4EfrZ7rrA1l36UCSKRaXQEy-Rp6GDcsPvFJ-QFE,303
1
+ pytrilogy-0.0.3.95.dist-info/licenses/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
2
+ trilogy/__init__.py,sha256=2SHgfndSm3yWw7j2feLaNCtzQoSJCcpfq9h1nEy7XF8,303
3
3
  trilogy/compiler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  trilogy/constants.py,sha256=eKb_EJvSqjN9tGbdVEViwdtwwh8fZ3-jpOEDqL71y70,1691
5
- trilogy/engine.py,sha256=OK2RuqCIUId6yZ5hfF8J1nxGP0AJqHRZiafcowmW0xc,1728
6
- trilogy/executor.py,sha256=tcowEz8I7zbwLnuTr7BlGJ5wnt1JKBNffXbm5ywkNv8,17032
5
+ trilogy/engine.py,sha256=3MiADf5MKcmxqiHBuRqiYdsXiLj7oitDfVvXvHrfjkA,2178
6
+ trilogy/executor.py,sha256=AwzC9J2GFfipc4PupFa0mpx5GXghsr0v2djpDV0D70M,19559
7
7
  trilogy/parser.py,sha256=o4cfk3j3yhUFoiDKq9ZX_GjBF3dKhDjXEwb63rcBkBM,293
8
8
  trilogy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  trilogy/render.py,sha256=qQWwduymauOlB517UtM-VGbVe8Cswa4UJub5aGbSO6c,1512
10
10
  trilogy/utility.py,sha256=euQccZLKoYBz0LNg5tzLlvv2YHvXh9HArnYp1V3uXsM,763
11
- trilogy/authoring/__init__.py,sha256=e74k-Jep4DLYPQU_2m0aVsYlw5HKTOucAKtdTbd6f2g,2595
11
+ trilogy/authoring/__init__.py,sha256=3VQyDVexk-Lpk5oWFA26pvNkJELDiLbVbet5tv7Cmdg,2671
12
12
  trilogy/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  trilogy/core/constants.py,sha256=nizWYDCJQ1bigQMtkNIEMNTcN0NoEAXiIHLzpelxQ24,201
14
- trilogy/core/enums.py,sha256=RQRkpGHLtcBKAO6jZnmGVtSUnb00Q2rP56ltYGdfTok,8294
15
- trilogy/core/env_processor.py,sha256=pD_YYuDG6CMybmwW9H2w958RloA7lEeVbzKXP6ltz2o,4078
16
- trilogy/core/environment_helpers.py,sha256=VvPIiFemqaLLpIpLIqprfu63K7muZ1YzNg7UZIUph8w,8267
14
+ trilogy/core/enums.py,sha256=EusAzz7o_YrWf64TLIED7MfziFOJk8EHM8se5W3nyJk,8644
15
+ trilogy/core/env_processor.py,sha256=H-rr2ALj31l5oh3FqeI47Qju6OOfiXBacXNJGNZ92zQ,4521
16
+ trilogy/core/environment_helpers.py,sha256=TRlqVctqIRBxzfjRBmpQsAVoiCcsEKBhG1B6PUE0l1M,12743
17
17
  trilogy/core/ergonomics.py,sha256=e-7gE29vPLFdg0_A1smQ7eOrUwKl5VYdxRSTddHweRA,1631
18
- trilogy/core/exceptions.py,sha256=jYEduuMehcMkmCpf-OC_taELPZm7qNfeSNzIWkDYScs,707
19
- trilogy/core/functions.py,sha256=hnfcNjAD-XQ572vEwuUEAdBf8zKFWYwPeHIpESjUpZs,32928
20
- trilogy/core/graph_models.py,sha256=zBzUwhYpnDJG91pWtk9ngw1WiTgHkMawyrqXptcGWGA,3847
21
- trilogy/core/internal.py,sha256=wFx4e1I0mtx159YFShSXeUBSQ82NINtAbOI-92RX4i8,2151
18
+ trilogy/core/exceptions.py,sha256=0Lmc3awJYx94k6uifbHc-EIqlFGV6YrX0QIwP84D4a4,1150
19
+ trilogy/core/functions.py,sha256=ESUWMRmwtavwCLl6z1NP9EFzWTJoXn3orTaaOSsj33Q,33093
20
+ trilogy/core/graph_models.py,sha256=jfYjDQoMtTkSM3n16BCYfhmvAwMHMU-nuQamlYkwzdM,3356
21
+ trilogy/core/internal.py,sha256=r9QagDB2GvpqlyD_I7VrsfbVfIk5mnok2znEbv72Aa4,2681
22
22
  trilogy/core/optimization.py,sha256=ojpn-p79lr03SSVQbbw74iPCyoYpDYBmj1dbZ3oXCjI,8860
23
- trilogy/core/query_processor.py,sha256=5aFgv-2LVM1Uku9cR_tFuTRDwyLnxc95bCMAHeFy2AY,20332
23
+ trilogy/core/query_processor.py,sha256=uqygDJqkjIH4vLP-lbGRgTN7rRcYEkr3KGqNimNw_80,20345
24
24
  trilogy/core/utility.py,sha256=3VC13uSQWcZNghgt7Ot0ZTeEmNqs__cx122abVq9qhM,410
25
25
  trilogy/core/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- trilogy/core/models/author.py,sha256=31WLOzOJMBoISjiIAAkY6wnH1Om8PPA_dh9tu17_djs,81553
27
- trilogy/core/models/build.py,sha256=Eew1P6mNNB7ywSb37sw4XBvJ-yyJK5vg99oIXgqgXAw,70529
26
+ trilogy/core/models/author.py,sha256=ZSKEJ6Vg4otpI_m7_JuGyrFM8dZV1HaxBwprvDSwUzo,81149
27
+ trilogy/core/models/build.py,sha256=ZwJJGyp4rVsISvL8Er_AxQdVJrafYc4fesSj4MNgoxU,70615
28
28
  trilogy/core/models/build_environment.py,sha256=mpx7MKGc60fnZLVdeLi2YSREy7eQbQYycCrP4zF-rHU,5258
29
- trilogy/core/models/core.py,sha256=nnz3ZROlVT18uygEWqqbfbHmcJkm2UC3VVCrsri_-K0,12836
29
+ trilogy/core/models/core.py,sha256=EofJ8-kltNr_7oFhyCPqauVX1bSJzJI5xOp0eMP_vlA,12892
30
30
  trilogy/core/models/datasource.py,sha256=wogTevZ-9CyUW2a8gjzqMCieircxi-J5lkI7EOAZnck,9596
31
- trilogy/core/models/environment.py,sha256=0IHSCFf5e5b4LPQN3vmjumtfM1iD1tN4WMoUr0UqxZI,27855
32
- trilogy/core/models/execute.py,sha256=PLSwllj0RnViY_R5ZKjyuZIZJvfOYDJn_Af-tBthzGM,41842
31
+ trilogy/core/models/environment.py,sha256=hwTIRnJgaHUdCYof7U5A9NPitGZ2s9yxqiW5O2SaJ9Y,28759
32
+ trilogy/core/models/execute.py,sha256=k2--2xUNuoaObkzutYaS5sdUFnY9zT_UKdU2rViq9XQ,42106
33
33
  trilogy/core/optimizations/__init__.py,sha256=YH2-mGXZnVDnBcWVi8vTbrdw7Qs5TivG4h38rH3js_I,290
34
34
  trilogy/core/optimizations/base_optimization.py,sha256=gzDOKImoFn36k7XBD3ysEYDnbnb6vdVIztUfFQZsGnM,513
35
35
  trilogy/core/optimizations/inline_datasource.py,sha256=2sWNRpoRInnTgo9wExVT_r9RfLAQHI57reEV5cGHUcg,4329
@@ -50,18 +50,17 @@ trilogy/core/processing/node_generators/filter_node.py,sha256=ArBsQJl-4fWBJWCE28
50
50
  trilogy/core/processing/node_generators/group_node.py,sha256=8HJ1lkOvIXfX3xoS2IMbM_wCu_mT0J_hQ7xnTaxsVlo,6611
51
51
  trilogy/core/processing/node_generators/group_to_node.py,sha256=jKcNCDOY6fNblrdZwaRU0sbUSr9H0moQbAxrGgX6iGA,3832
52
52
  trilogy/core/processing/node_generators/multiselect_node.py,sha256=GWV5yLmKTe1yyPhN60RG1Rnrn4ktfn9lYYXi_FVU4UI,7061
53
- trilogy/core/processing/node_generators/node_merge_node.py,sha256=rb6ltJyhAUFairG6LZJ111Zm2uQhXWsSZfSERahUNGc,18258
53
+ trilogy/core/processing/node_generators/node_merge_node.py,sha256=83FkcYuOFyDY0_0NWhL45MAT5J_6Y6L1h357WrJPzaI,18230
54
54
  trilogy/core/processing/node_generators/recursive_node.py,sha256=l5zdh0dURKwmAy8kK4OpMtZfyUEQRk6N-PwSWIyBpSM,2468
55
55
  trilogy/core/processing/node_generators/rowset_node.py,sha256=5L5u6xz1In8EaHQdcYgR2si-tz9WB9YLXURo4AkUT9A,6630
56
- trilogy/core/processing/node_generators/select_merge_node.py,sha256=Cv2GwNiYSmwewjuK8T3JB3pbgrLZFPsB75DCP153BMA,22818
57
- trilogy/core/processing/node_generators/select_merge_node_v2.py,sha256=1HQedwstFbk3xc7B09ElJ3mMoIKixtkcCqjDIBfsxck,25707
56
+ trilogy/core/processing/node_generators/select_merge_node.py,sha256=KQvGoNT5ZBWQ_caEomRTtG1PKZC7OPT4PKfY0QmwMGE,22270
58
57
  trilogy/core/processing/node_generators/select_node.py,sha256=Ta1G39V94gjX_AgyZDz9OqnwLz4BjY3D6Drx9YpziMQ,3555
59
58
  trilogy/core/processing/node_generators/synonym_node.py,sha256=AnAsa_Wj50NJ_IK0HSgab_7klYmKVrv0WI1uUe-GvEY,3766
60
59
  trilogy/core/processing/node_generators/union_node.py,sha256=VNo6Oey4p8etU9xrOh2oTT2lIOTvY6PULUPRvVa2uxU,2877
61
60
  trilogy/core/processing/node_generators/unnest_node.py,sha256=ueOQtoTf2iJHO09RzWHDFQ5iKZq2fVhGf2KAF2U2kU8,2677
62
61
  trilogy/core/processing/node_generators/window_node.py,sha256=A90linr4pkZtTNfn9k2YNLqrJ_SFII3lbHxB-BC6mI8,6688
63
62
  trilogy/core/processing/node_generators/select_helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
- trilogy/core/processing/node_generators/select_helpers/datasource_injection.py,sha256=mKCDHxr2eyrdozXEHq_HvuwtBgnb9JPlImJIx6JGX34,7834
63
+ trilogy/core/processing/node_generators/select_helpers/datasource_injection.py,sha256=m2YQ4OmG0N2O61a7NEq1ZzbTa7JsCC00lxB2ymjcYRI,8224
65
64
  trilogy/core/processing/nodes/__init__.py,sha256=zTge1EzwzEydlcMliIFO_TT7h7lS8l37lyZuQDir1h0,5487
66
65
  trilogy/core/processing/nodes/base_node.py,sha256=C_CjlOzlGMXckyV0b_PJZerpopNesRCKfambMq7Asvc,18221
67
66
  trilogy/core/processing/nodes/filter_node.py,sha256=5VtRfKbCORx0dV-vQfgy3gOEkmmscL9f31ExvlODwvY,2461
@@ -73,12 +72,17 @@ trilogy/core/processing/nodes/union_node.py,sha256=hLAXXVWqEgMWi7dlgSHfCF59fon64
73
72
  trilogy/core/processing/nodes/unnest_node.py,sha256=oLKMMNMx6PLDPlt2V5neFMFrFWxET8r6XZElAhSNkO0,2181
74
73
  trilogy/core/processing/nodes/window_node.py,sha256=JXJ0iVRlSEM2IBr1TANym2RaUf_p5E_l2sNykRzXWDo,1710
75
74
  trilogy/core/statements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
- trilogy/core/statements/author.py,sha256=6cGCuKERNkH22T6iTsgoNp5CcIFwknF3WX-UmegbUPA,15409
75
+ trilogy/core/statements/author.py,sha256=VFzylve72fw0tqMSP5Yiwp8--_r92b9zzX1XAdxuTYQ,15963
77
76
  trilogy/core/statements/build.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
- trilogy/core/statements/common.py,sha256=KxEmz2ySySyZ6CTPzn0fJl5NX2KOk1RPyuUSwWhnK1g,759
79
- trilogy/core/statements/execute.py,sha256=pfr1CZ_Cx1qQ-7LDyRI0JUfvtxBr_GGv-VeqiAjr43g,1406
77
+ trilogy/core/statements/common.py,sha256=VnVLULQg1TJLNUFzJaROT1tsf2ewk3IpuhvZaP36R6A,535
78
+ trilogy/core/statements/execute.py,sha256=2ev8nnf41MAgJJAb5gStd__d9hZNOR2pSUTYGFdHvhU,2342
79
+ trilogy/core/validation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
+ trilogy/core/validation/common.py,sha256=xMx5jF3HDydaGwp9ybBo_NVWOqsmo_mimofdhAv8Kjs,3139
81
+ trilogy/core/validation/concept.py,sha256=HLY8zzMP15VOotvT3lVLh7h_lLJ9evZJ3qaG9huwG50,4344
82
+ trilogy/core/validation/datasource.py,sha256=92l0T0kxzBnGFT1zW_LvZHMkvkfoWvqQf0Nk4qysWts,6346
83
+ trilogy/core/validation/environment.py,sha256=8TuLfIE49zSEtvHPBlNC8QJ5fnS0QZqM0TFpHhy2GN0,2790
80
84
  trilogy/dialect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
- trilogy/dialect/base.py,sha256=_L5wHBHz8v4Us3tu4QIupKuaObmyhWhyDuroT95wUbo,48228
85
+ trilogy/dialect/base.py,sha256=QwjQm2os5prVgCaWgpyk1bIL0okCMOGFQdAnKcYXmIo,49392
82
86
  trilogy/dialect/bigquery.py,sha256=XS3hpybeowgfrOrkycAigAF3NX2YUzTzfgE6f__2fT4,4316
83
87
  trilogy/dialect/common.py,sha256=tSthIZOXXRPQ4KeMKnDDsH7KlTmf2EVqigVtLyoc4zc,6071
84
88
  trilogy/dialect/config.py,sha256=olnyeVU5W5T6b9-dMeNAnvxuPlyc2uefb7FRME094Ec,3834
@@ -88,7 +92,7 @@ trilogy/dialect/enums.py,sha256=FRNYQ5-w-B6-X0yXKNU5g9GowsMlERFogTC5u2nxL_s,4740
88
92
  trilogy/dialect/postgres.py,sha256=el2PKwfyvWGk5EZtLudqAH5ewLitY1sFHJiocBSyxyM,3393
89
93
  trilogy/dialect/presto.py,sha256=k1IaeilR3nzPC9Hp7jlAdzJ7TsuxB3LQTBQ28MYE7O8,3715
90
94
  trilogy/dialect/snowflake.py,sha256=T6_mKfhpDazB1xQxqFLS2AJwzwzBcPYY6_qxRnAtFBs,3326
91
- trilogy/dialect/sql_server.py,sha256=HnUEvb8Yjl6MnMWTITzpFPZgDajhGzfDPz5A8dDerak,3279
95
+ trilogy/dialect/sql_server.py,sha256=jJU5gv3V3B4xjMP12cWgnpVeRzbrIw8vcJ2zyMv9iyI,3353
92
96
  trilogy/hooks/__init__.py,sha256=T3SF3phuUDPLXKGRVE_Lf9mzuwoXWyaLolncR_1kY30,144
93
97
  trilogy/hooks/base_hook.py,sha256=I_l-NBMNC7hKTDx1JgHZPVOOCvLQ36m2oIGaR5EUMXY,1180
94
98
  trilogy/hooks/graph_hook.py,sha256=5BfR7Dt0bgEsCLgwjowgCsVkboGYfVJGOz8g9mqpnos,4756
@@ -99,9 +103,9 @@ trilogy/parsing/common.py,sha256=550-L0444GUuBFdiDWkOg_DxnMXtcJFUMES2R5zlwik,310
99
103
  trilogy/parsing/config.py,sha256=Z-DaefdKhPDmSXLgg5V4pebhSB0h590vI0_VtHnlukI,111
100
104
  trilogy/parsing/exceptions.py,sha256=Xwwsv2C9kSNv2q-HrrKC1f60JNHShXcCMzstTSEbiCw,154
101
105
  trilogy/parsing/helpers.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
102
- trilogy/parsing/parse_engine.py,sha256=minAI04kKs5uZqRumafMCvC9lRwlcXCLmDigcNOF_7w,80639
106
+ trilogy/parsing/parse_engine.py,sha256=fZGFNN7PEVJ7_tk0GxBHJQerIJTifbrjoMcHfTR_TYk,81647
103
107
  trilogy/parsing/render.py,sha256=HSNntD82GiiwHT-TWPLXAaIMWLYVV5B5zQEsgwrHIBE,19605
104
- trilogy/parsing/trilogy.lark,sha256=e2YVSxqzRov08AydtDSA8aqSJU2M1eJaidMEkHCdsYE,15896
108
+ trilogy/parsing/trilogy.lark,sha256=9-SMrKFGZLdBTNheK1szif0VYOIt5m0xhVd8pOFCByU,16267
105
109
  trilogy/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
110
  trilogy/scripts/trilogy.py,sha256=1L0XrH4mVHRt1C9T1HnaDv2_kYEfbWTb5_-cBBke79w,3774
107
111
  trilogy/std/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -112,8 +116,8 @@ trilogy/std/money.preql,sha256=XWwvAV3WxBsHX9zfptoYRnBigcfYwrYtBHXTME0xJuQ,2082
112
116
  trilogy/std/net.preql,sha256=WZCuvH87_rZntZiuGJMmBDMVKkdhTtxeHOkrXNwJ1EE,416
113
117
  trilogy/std/ranking.preql,sha256=LDoZrYyz4g3xsII9XwXfmstZD-_92i1Eox1UqkBIfi8,83
114
118
  trilogy/std/report.preql,sha256=LbV-XlHdfw0jgnQ8pV7acG95xrd1-p65fVpiIc-S7W4,202
115
- pytrilogy-0.0.3.93.dist-info/METADATA,sha256=Cyriy0EbhAniv3y6S2WNWQdYcNJK1iePuzmd2JnbW0U,9746
116
- pytrilogy-0.0.3.93.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
117
- pytrilogy-0.0.3.93.dist-info/entry_points.txt,sha256=ewBPU2vLnVexZVnB-NrVj-p3E-4vukg83Zk8A55Wp2w,56
118
- pytrilogy-0.0.3.93.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
119
- pytrilogy-0.0.3.93.dist-info/RECORD,,
119
+ pytrilogy-0.0.3.95.dist-info/METADATA,sha256=00qsW428K_K33ZhoMDKEMPViV1eCY6Gm6MJZ71fRHRo,10441
120
+ pytrilogy-0.0.3.95.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
121
+ pytrilogy-0.0.3.95.dist-info/entry_points.txt,sha256=ewBPU2vLnVexZVnB-NrVj-p3E-4vukg83Zk8A55Wp2w,56
122
+ pytrilogy-0.0.3.95.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
123
+ pytrilogy-0.0.3.95.dist-info/RECORD,,
trilogy/__init__.py CHANGED
@@ -4,6 +4,6 @@ from trilogy.dialect.enums import Dialects
4
4
  from trilogy.executor import Executor
5
5
  from trilogy.parser import parse
6
6
 
7
- __version__ = "0.0.3.93"
7
+ __version__ = "0.0.3.95"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -41,7 +41,9 @@ from trilogy.core.models.core import (
41
41
  DataType,
42
42
  ListWrapper,
43
43
  MapType,
44
+ NumericType,
44
45
  StructType,
46
+ TraitDataType,
45
47
  )
46
48
  from trilogy.core.models.datasource import Address, Datasource, DatasourceMetadata
47
49
  from trilogy.core.models.environment import Environment
@@ -78,6 +80,7 @@ __all__ = [
78
80
  "DataType",
79
81
  "StructType",
80
82
  "ArrayType",
83
+ "NumericType",
81
84
  "Grain",
82
85
  "RowsetDerivationStatement",
83
86
  "MapType",
@@ -120,4 +123,5 @@ __all__ = [
120
123
  "HasUUID",
121
124
  "ImportStatement",
122
125
  "Address",
126
+ "TraitDataType",
123
127
  ]
trilogy/core/enums.py CHANGED
@@ -240,6 +240,7 @@ class FunctionType(Enum):
240
240
  # CONSTANTS
241
241
  CURRENT_DATE = "current_date"
242
242
  CURRENT_DATETIME = "current_datetime"
243
+ CURRENT_TIMESTAMP = "current_timestamp"
243
244
 
244
245
 
245
246
  class FunctionClass(Enum):
@@ -378,3 +379,15 @@ class IOType(Enum):
378
379
  if isinstance(value, str) and value.lower() != value:
379
380
  return IOType(value.lower())
380
381
  return super()._missing_(value)
382
+
383
+
384
+ class ValidationScope(Enum):
385
+ ALL = "all"
386
+ CONCEPTS = "concepts"
387
+ DATASOURCES = "datasources"
388
+
389
+ @classmethod
390
+ def _missing_(cls, value):
391
+ if isinstance(value, str) and value.lower() != value:
392
+ return ValidationScope(value.lower())
393
+ return super()._missing_(value)