pytrilogy 0.0.1.118__py3-none-any.whl → 0.0.2.1__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 (45) hide show
  1. {pytrilogy-0.0.1.118.dist-info → pytrilogy-0.0.2.1.dist-info}/METADATA +1 -1
  2. pytrilogy-0.0.2.1.dist-info/RECORD +82 -0
  3. {pytrilogy-0.0.1.118.dist-info → pytrilogy-0.0.2.1.dist-info}/WHEEL +1 -1
  4. trilogy/__init__.py +1 -1
  5. trilogy/constants.py +6 -0
  6. trilogy/core/enums.py +7 -2
  7. trilogy/core/env_processor.py +43 -19
  8. trilogy/core/functions.py +1 -0
  9. trilogy/core/models.py +666 -146
  10. trilogy/core/optimization.py +31 -28
  11. trilogy/core/optimizations/inline_constant.py +4 -1
  12. trilogy/core/optimizations/inline_datasource.py +25 -4
  13. trilogy/core/optimizations/predicate_pushdown.py +94 -54
  14. trilogy/core/processing/concept_strategies_v3.py +69 -39
  15. trilogy/core/processing/graph_utils.py +3 -3
  16. trilogy/core/processing/node_generators/__init__.py +0 -2
  17. trilogy/core/processing/node_generators/basic_node.py +30 -17
  18. trilogy/core/processing/node_generators/filter_node.py +3 -1
  19. trilogy/core/processing/node_generators/node_merge_node.py +345 -96
  20. trilogy/core/processing/node_generators/rowset_node.py +18 -16
  21. trilogy/core/processing/node_generators/select_node.py +44 -83
  22. trilogy/core/processing/nodes/__init__.py +2 -0
  23. trilogy/core/processing/nodes/base_node.py +22 -5
  24. trilogy/core/processing/nodes/filter_node.py +3 -0
  25. trilogy/core/processing/nodes/group_node.py +20 -2
  26. trilogy/core/processing/nodes/merge_node.py +32 -18
  27. trilogy/core/processing/nodes/select_node_v2.py +17 -3
  28. trilogy/core/processing/utility.py +100 -8
  29. trilogy/core/query_processor.py +77 -24
  30. trilogy/dialect/base.py +11 -46
  31. trilogy/dialect/bigquery.py +1 -1
  32. trilogy/dialect/common.py +11 -0
  33. trilogy/dialect/duckdb.py +1 -1
  34. trilogy/dialect/presto.py +1 -0
  35. trilogy/hooks/graph_hook.py +50 -5
  36. trilogy/hooks/query_debugger.py +1 -0
  37. trilogy/parsing/common.py +8 -5
  38. trilogy/parsing/parse_engine.py +48 -27
  39. trilogy/parsing/render.py +13 -6
  40. trilogy/parsing/trilogy.lark +12 -7
  41. pytrilogy-0.0.1.118.dist-info/RECORD +0 -83
  42. trilogy/core/processing/node_generators/concept_merge_node.py +0 -214
  43. {pytrilogy-0.0.1.118.dist-info → pytrilogy-0.0.2.1.dist-info}/LICENSE.md +0 -0
  44. {pytrilogy-0.0.1.118.dist-info → pytrilogy-0.0.2.1.dist-info}/entry_points.txt +0 -0
  45. {pytrilogy-0.0.1.118.dist-info → pytrilogy-0.0.2.1.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytrilogy
3
- Version: 0.0.1.118
3
+ Version: 0.0.2.1
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -0,0 +1,82 @@
1
+ trilogy/__init__.py,sha256=f4K50J-SBruXMjFtcHLn_pB9eN7oCkbwqmtEjcxjSoM,290
2
+ trilogy/compiler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ trilogy/constants.py,sha256=KIvi-cgU4R9urNgDdGiCsRkCrzjAfM4xGHhZb1SVy2w,881
4
+ trilogy/engine.py,sha256=R5ubIxYyrxRExz07aZCUfrTsoXCHQ8DKFTDsobXdWdA,1102
5
+ trilogy/executor.py,sha256=5cRbU4Rj7p1pNV76rfp1pz704Hx_0q8_O8HFURjgXxQ,11016
6
+ trilogy/parser.py,sha256=UtuqSiGiCjpMAYgo1bvNq-b7NSzCA5hzbUW31RXaMII,281
7
+ trilogy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ trilogy/utility.py,sha256=zM__8r29EsyDW7K9VOHz8yvZC2bXFzh7xKy3cL7GKsk,707
9
+ trilogy/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ trilogy/core/constants.py,sha256=LL8NLvxb3HRnAjvofyLRXqQJijLcYiXAQYQzGarVD-g,128
11
+ trilogy/core/enums.py,sha256=DWKPuShM_DbyAenjNFOAxcIH2l0QC9WgIwqZKPQqk_o,5850
12
+ trilogy/core/env_processor.py,sha256=Wpy-iiduBwHntTsQTYWBO1O0i3Ij9_VoL3d4IWDEoj4,2126
13
+ trilogy/core/environment_helpers.py,sha256=mzBDHhdF9ssZ_-LY8CcaM_ddfJavkpRYrFImUd3cjXI,5972
14
+ trilogy/core/ergonomics.py,sha256=w3gwXdgrxNHCuaRdyKg73t6F36tj-wIjQf47WZkHmJk,1465
15
+ trilogy/core/exceptions.py,sha256=NvV_4qLOgKXbpotgRf7c8BANDEvHxlqRPaA53IThQ2o,561
16
+ trilogy/core/functions.py,sha256=xISGHMiUR9hFyoZe2l3VLTMO6UEtyGHQcMuovzlVRqw,9492
17
+ trilogy/core/graph_models.py,sha256=oJUMSpmYhqXlavckHLpR07GJxuQ8dZ1VbB1fB0KaS8c,2036
18
+ trilogy/core/internal.py,sha256=jNGFHKENnbMiMCtAgsnLZYVSENDK4b5ALecXFZpTDzQ,1075
19
+ trilogy/core/models.py,sha256=432UOrJNzdY0_2vCbeBrNBDQOG_v-WaWqYSniM1CJpE,134387
20
+ trilogy/core/optimization.py,sha256=iX8BCh2BIEPJ6cYlcn7piDKFfig47azphhyqkwkYJM4,4291
21
+ trilogy/core/query_processor.py,sha256=PROehLEOMOuKy1EAUeIgdfGq1LrJsX0N7Z2qDED6S30,17580
22
+ trilogy/core/optimizations/__init__.py,sha256=pxRzNzd2g8oRMy4f_ub5va6bNS2pd4hnyp9JBzTKc1E,300
23
+ trilogy/core/optimizations/base_optimization.py,sha256=tWWT-xnTbnEU-mNi_isMNbywm8B9WTRsNFwGpeh3rqE,468
24
+ trilogy/core/optimizations/inline_constant.py,sha256=kHNyc2UoaPVdYfVAPAFwnWuk4sJ_IF5faRtVcDOrBtw,1110
25
+ trilogy/core/optimizations/inline_datasource.py,sha256=KiwZ4fnRnSOVK8zzdwMAkafszo3fNn5LY8xgb0X1CbI,3194
26
+ trilogy/core/optimizations/predicate_pushdown.py,sha256=mduJn4zzKmLVNUja60ZlY6LlNp389OwjEbq2Rj8K6co,5389
27
+ trilogy/core/processing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ trilogy/core/processing/concept_strategies_v3.py,sha256=hmbck3a23N61HfMwC2z3lxA6Yms9TP7Lm3Aw7GiDcMA,23765
29
+ trilogy/core/processing/graph_utils.py,sha256=aq-kqk4Iado2HywDxWEejWc-7PGO6Oa-ZQLAM6XWPHw,1199
30
+ trilogy/core/processing/utility.py,sha256=hgfPfz5FlghN8edIVGTQ21eDUof5EMvnl3Vu64hjfqY,13289
31
+ trilogy/core/processing/node_generators/__init__.py,sha256=-mzYkRsaRNa_dfTckYkKVFSR8h8a3ihEiPJDU_tAmDo,672
32
+ trilogy/core/processing/node_generators/basic_node.py,sha256=uD6noJOgrtmhjb-1aa-vD8sQ97s9Tya6wbso7V_AdyE,2819
33
+ trilogy/core/processing/node_generators/common.py,sha256=liZDth7mvhkF_sUFXK7JitJsiaKD132w3ySLbF7l-nE,8956
34
+ trilogy/core/processing/node_generators/filter_node.py,sha256=5B7UCK84A9lGgJ7EjCiC7YGWWM1xPyQGHkBwZgYypFM,4585
35
+ trilogy/core/processing/node_generators/group_node.py,sha256=xWI1xNIXEOj6jlRGD9hcv2_vVNvY6lpzJl6pQ8HuFBE,2988
36
+ trilogy/core/processing/node_generators/group_to_node.py,sha256=BzPdYwzoo8gRMH7BDffTTXq4z-mjfCEzvfB5I-P0_nw,2941
37
+ trilogy/core/processing/node_generators/multiselect_node.py,sha256=vP84dnLQy6dtypi6mUbt9sMAcmmrTgQ1Oz4GI6X1IEo,6421
38
+ trilogy/core/processing/node_generators/node_merge_node.py,sha256=YivTVrTEUJuQbQAHFVB2lUD4mJYQ-kTVVpwY4oT9A-Y,14664
39
+ trilogy/core/processing/node_generators/rowset_node.py,sha256=2ROd2c1_o4h5sbnDdaiL1o9UiiwyYw-B6OKyfHYNe0A,6188
40
+ trilogy/core/processing/node_generators/select_node.py,sha256=uk02lRvSJB1gWYRcSNfRZ8aYk3fME_tgg0I6EZyuxkI,19052
41
+ trilogy/core/processing/node_generators/unnest_node.py,sha256=6CH66eGwpadNX7TzUhWZ8aqIisOtQeHINbLV6X3QBUk,1779
42
+ trilogy/core/processing/node_generators/window_node.py,sha256=9nXUXUgQrNczU1gaOqhOZPNzCUxw-lkxt0R7HORI6ss,2582
43
+ trilogy/core/processing/nodes/__init__.py,sha256=-8ONG7Nqa6sNLpst5wNNyMigyaHRfUKGdE3xce8E3mM,3998
44
+ trilogy/core/processing/nodes/base_node.py,sha256=q1G4FO3Q4OuboWL8EaJgJ4jcnnqM9QsothMIcF2ot1g,11161
45
+ trilogy/core/processing/nodes/filter_node.py,sha256=ImUHYj5G5eHbOtki-ZMR31Op38wKOjR1xu_ETiE_D6I,1932
46
+ trilogy/core/processing/nodes/group_node.py,sha256=5dqGlonXG5Ou7HRSsTStbM1KyxeDSZROz9qKTjOUMEc,5166
47
+ trilogy/core/processing/nodes/merge_node.py,sha256=W7ryL9rceylCQGNgcuGY-dSiNoIz8qrbpJXKzg_Niwo,14056
48
+ trilogy/core/processing/nodes/select_node_v2.py,sha256=COu-WPuyabGAc3HTkJB-_7eNzR4OgxIL4YDuZIRrST0,7179
49
+ trilogy/core/processing/nodes/unnest_node.py,sha256=JFtm90IVM-46aCYkTNIaJah6v9ApAfonjVhcVM1HmDE,1903
50
+ trilogy/core/processing/nodes/window_node.py,sha256=X7qxLUKd3tekjUUsmH_4vz5b-U89gMnGd04VBxuu2Ns,1280
51
+ trilogy/dialect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
+ trilogy/dialect/base.py,sha256=EZCP3xU8-B4xpU1pFFew4CGtkNWignbyPll6OTENFLg,29832
53
+ trilogy/dialect/bigquery.py,sha256=BAN2o0SOuLvzLYLV7Sc11woapS5L7Cc36aMBeaphW5k,2905
54
+ trilogy/dialect/common.py,sha256=5jdOHWIj3Xv8F8y5mnyWHLjxD_we2fncM-ZnNetJP7U,2781
55
+ trilogy/dialect/config.py,sha256=tLVEMctaTDhUgARKXUNfHUcIolGaALkQ0RavUvXAY4w,2994
56
+ trilogy/dialect/duckdb.py,sha256=JQPnR5F39iDQXfTccKhbq7xWYGzYc0dPpn5vo0Qd_Vk,3076
57
+ trilogy/dialect/enums.py,sha256=4NdpsydBpDn6jnh0JzFz5VvQEtnShErWtWHVyT6TNpw,3948
58
+ trilogy/dialect/postgres.py,sha256=r47xbCA7nfEYENofiVfLZ-SnReNfDmUmW4OSHVkkP4E,3206
59
+ trilogy/dialect/presto.py,sha256=ouSVNbs7e3eEc20emLfxKyRjdINSibPGUFL4X9OwboA,3163
60
+ trilogy/dialect/snowflake.py,sha256=N3HknYgN-fjD7BLX1Ucj-ss_ku2Ox8DgLsF3BIHutHo,2941
61
+ trilogy/dialect/sql_server.py,sha256=HX68vNTrcDaTnOxe6Zbx_PBgrO42e2VuThxO6CYQ2cY,3026
62
+ trilogy/hooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
+ trilogy/hooks/base_hook.py,sha256=Xkb-A2qCHozYjum0A36zOy5PwTVwrP3NLDF0U2GpgHo,1100
64
+ trilogy/hooks/graph_hook.py,sha256=onHvMQPwj_KOS3HOTpRFiy7QLLKAiycq2MzJ_Q0Oh5Y,2467
65
+ trilogy/hooks/query_debugger.py,sha256=NDChfkPmmW-KINa4TaQmDe_adGiwsKFdGLDSYpbodeU,4282
66
+ trilogy/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
+ trilogy/parsing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
+ trilogy/parsing/common.py,sha256=8MDRPccWymtVkHVQMzESjL5tOH79flWU5jo6Ys-C5UQ,5963
69
+ trilogy/parsing/config.py,sha256=Z-DaefdKhPDmSXLgg5V4pebhSB0h590vI0_VtHnlukI,111
70
+ trilogy/parsing/exceptions.py,sha256=92E5i2frv5hj9wxObJZsZqj5T6bglvPzvdvco_vW1Zk,38
71
+ trilogy/parsing/helpers.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
72
+ trilogy/parsing/parse_engine.py,sha256=hPvPZuO_ZBjoKRMh-bKzhnt6oo8R5l4gL9bJqZoMUfs,57619
73
+ trilogy/parsing/render.py,sha256=ym8DcgU-frNxd16ThWYGJFyChF-d0yd2gp9tEA6RFJU,12059
74
+ trilogy/parsing/trilogy.lark,sha256=4VXqLWOdxJsfZoJIp9Ug1G3p_LrXRDm5C2yAxaRgq98,10993
75
+ trilogy/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
+ trilogy/scripts/trilogy.py,sha256=PHxvv6f2ODv0esyyhWxlARgra8dVhqQhYl0lTrSyVNo,3729
77
+ pytrilogy-0.0.2.1.dist-info/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
78
+ pytrilogy-0.0.2.1.dist-info/METADATA,sha256=YN0xCd-8tn38c-px20-D1WgFDUjn-P6J6hNtsyhUFmE,7876
79
+ pytrilogy-0.0.2.1.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
80
+ pytrilogy-0.0.2.1.dist-info/entry_points.txt,sha256=0petKryjvvtEfTlbZC1AuMFumH_WQ9v8A19LvoS6G6c,54
81
+ pytrilogy-0.0.2.1.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
82
+ pytrilogy-0.0.2.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.1.0)
2
+ Generator: setuptools (73.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
trilogy/__init__.py CHANGED
@@ -4,6 +4,6 @@ from trilogy.executor import Executor
4
4
  from trilogy.parser import parse
5
5
  from trilogy.constants import CONFIG
6
6
 
7
- __version__ = "0.0.1.118"
7
+ __version__ = "0.0.2.1"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
trilogy/constants.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from logging import getLogger
2
2
  from dataclasses import dataclass, field
3
3
  from enum import Enum
4
+ import random
4
5
 
5
6
  logger = getLogger("trilogy")
6
7
 
@@ -34,7 +35,12 @@ class Config:
34
35
  validate_missing: bool = True
35
36
  optimizations: Optimizations = field(default_factory=Optimizations)
36
37
 
38
+ def set_random_seed(self, seed: int):
39
+ random.seed(seed)
40
+
37
41
 
38
42
  CONFIG = Config()
39
43
 
44
+ CONFIG.set_random_seed(42)
45
+
40
46
  CONFIG.strict_mode = True
trilogy/core/enums.py CHANGED
@@ -43,7 +43,6 @@ class PurposeLineage(Enum):
43
43
  ROOT = "root"
44
44
  ROWSET = "rowset"
45
45
  MULTISELECT = "multiselect"
46
- MERGE = "merge"
47
46
 
48
47
 
49
48
  class Granularity(Enum):
@@ -263,7 +262,6 @@ class DatePart(Enum):
263
262
  class SourceType(Enum):
264
263
  FILTER = "filter"
265
264
  SELECT = "select"
266
- MERGE = "merge"
267
265
  ABSTRACT = "abstract"
268
266
  DIRECT_SELECT = "direct_select"
269
267
  GROUP = "group"
@@ -271,8 +269,15 @@ class SourceType(Enum):
271
269
  UNNEST = "unnest"
272
270
  CONSTANT = "constant"
273
271
  ROWSET = "rowset"
272
+ MERGE = "merge"
274
273
 
275
274
 
276
275
  class ShowCategory(Enum):
277
276
  MODELS = "models"
278
277
  CONCEPTS = "concepts"
278
+
279
+
280
+ class SelectFiltering(Enum):
281
+ NONE = "none"
282
+ EXPLICIT = "explicit" # the filtering contains only selected values
283
+ IMPLICIT = "implicit" # the filtering contains unselected values
@@ -3,37 +3,61 @@ from trilogy.core.graph_models import (
3
3
  concept_to_node,
4
4
  datasource_to_node,
5
5
  )
6
- from trilogy.core.models import Environment
7
- from trilogy.core.enums import PurposeLineage
6
+ from trilogy.core.models import Environment, Concept, Datasource
8
7
 
9
8
 
10
- def generate_graph(
11
- environment: Environment,
9
+ def add_concept(concept: Concept, g: ReferenceGraph):
10
+ g.add_node(concept)
11
+ # if we have sources, recursively add them
12
+ node_name = concept_to_node(concept)
13
+ if concept.sources:
14
+ for source in concept.sources:
15
+ generic = source.with_default_grain()
16
+ g.add_edge(generic, node_name)
17
+ for _, pseudonym in concept.pseudonyms.items():
18
+ pseudonym = pseudonym.with_default_grain()
19
+ pseudonym_node = concept_to_node(pseudonym)
20
+ if pseudonym_node.split("@")[0] == node_name.split("@")[0]:
21
+ continue
22
+ g.add_edge(pseudonym_node, node_name, pseudonym=True)
23
+ g.add_edge(node_name, pseudonym_node, pseudonym=True)
24
+ add_concept(pseudonym, g)
25
+
26
+
27
+ def generate_adhoc_graph(
28
+ concepts: list[Concept],
29
+ datasources: list[Datasource],
30
+ restrict_to_listed: bool = False,
12
31
  ) -> ReferenceGraph:
13
32
  g = ReferenceGraph()
14
33
 
15
34
  # add all parsed concepts
16
- for _, concept in environment.concepts.items():
17
- g.add_node(concept)
18
- # if we have sources, recursively add them
19
- if concept.sources:
20
- node_name = concept_to_node(concept)
21
- for source in concept.sources:
22
- generic = source.with_default_grain()
23
- g.add_edge(generic, node_name)
24
-
25
- # link the concept to the generic source
26
- if concept.derivation == PurposeLineage.MERGE:
27
- g.add_edge(node_name, generic)
28
- for _, dataset in environment.datasources.items():
35
+ for concept in concepts:
36
+ add_concept(concept, g)
37
+
38
+ for dataset in datasources:
29
39
  node = datasource_to_node(dataset)
30
40
  g.add_node(dataset, type="datasource", datasource=dataset)
31
41
  for concept in dataset.concepts:
42
+ if restrict_to_listed:
43
+ if concept_to_node(concept) not in g.nodes:
44
+ continue
32
45
  g.add_edge(node, concept)
33
46
  g.add_edge(concept, node)
34
47
  # if there is a key on a table at a different grain
35
48
  # add an FK edge to the canonical source, if it exists
36
49
  # for example, order ID on order product table
37
- g.add_edge(concept, concept.with_default_grain())
38
- g.add_edge(concept.with_default_grain(), concept)
50
+ default = concept.with_default_grain()
51
+ if concept != default:
52
+ g.add_edge(concept, default)
53
+ g.add_edge(default, concept)
39
54
  return g
55
+
56
+
57
+ def generate_graph(
58
+ environment: Environment,
59
+ ) -> ReferenceGraph:
60
+
61
+ return generate_adhoc_graph(
62
+ list(environment.concepts.values()), list(environment.datasources.values())
63
+ )
trilogy/core/functions.py CHANGED
@@ -163,6 +163,7 @@ def Max(args: list[Concept]) -> Function:
163
163
  DataType.DATE,
164
164
  DataType.DATETIME,
165
165
  DataType.TIMESTAMP,
166
+ DataType.BOOL,
166
167
  },
167
168
  arg_count=1,
168
169
  # output_grain=Grain(components=arguments),