pytrilogy 0.0.1.117__py3-none-any.whl → 0.0.1.118__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytrilogy
3
- Version: 0.0.1.117
3
+ Version: 0.0.1.118
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -1,8 +1,8 @@
1
- trilogy/__init__.py,sha256=1wHuIjygzuHzrQfHKZQ2GJsmw4tMvEXzwEJMg9Lb3Zc,292
1
+ trilogy/__init__.py,sha256=fYN8J2EkHXTX5cKVWpbBMQHilscbkhmZF-pMLoMqHFc,292
2
2
  trilogy/compiler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  trilogy/constants.py,sha256=u2dNxhwy0v-6HrvG1GcpDVvuhzdTH5fuyYNCxDPlr2E,770
4
4
  trilogy/engine.py,sha256=R5ubIxYyrxRExz07aZCUfrTsoXCHQ8DKFTDsobXdWdA,1102
5
- trilogy/executor.py,sha256=auuDykCHeqlRWIHOfBfgIIIntEctWaUC-VPJr1DQbYk,10217
5
+ trilogy/executor.py,sha256=5cRbU4Rj7p1pNV76rfp1pz704Hx_0q8_O8HFURjgXxQ,11016
6
6
  trilogy/parser.py,sha256=UtuqSiGiCjpMAYgo1bvNq-b7NSzCA5hzbUW31RXaMII,281
7
7
  trilogy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  trilogy/utility.py,sha256=zM__8r29EsyDW7K9VOHz8yvZC2bXFzh7xKy3cL7GKsk,707
@@ -13,10 +13,10 @@ trilogy/core/env_processor.py,sha256=SU-jpaGfoWLe9sGTeQYG1qjVnwGQ7TwctmnJRlfzluc
13
13
  trilogy/core/environment_helpers.py,sha256=mzBDHhdF9ssZ_-LY8CcaM_ddfJavkpRYrFImUd3cjXI,5972
14
14
  trilogy/core/ergonomics.py,sha256=w3gwXdgrxNHCuaRdyKg73t6F36tj-wIjQf47WZkHmJk,1465
15
15
  trilogy/core/exceptions.py,sha256=NvV_4qLOgKXbpotgRf7c8BANDEvHxlqRPaA53IThQ2o,561
16
- trilogy/core/functions.py,sha256=hXp-b29w3vNHQHpTU-VPXJqJaLferNwa681xQ3pf8R0,9129
16
+ trilogy/core/functions.py,sha256=fWuuPOeWRAiukTkXvTEu_NCSbu6eUmogtLGpC4ey2FI,9465
17
17
  trilogy/core/graph_models.py,sha256=oJUMSpmYhqXlavckHLpR07GJxuQ8dZ1VbB1fB0KaS8c,2036
18
18
  trilogy/core/internal.py,sha256=jNGFHKENnbMiMCtAgsnLZYVSENDK4b5ALecXFZpTDzQ,1075
19
- trilogy/core/models.py,sha256=U8gYAvRoob4uj3f-j3N5EwkbBs_tKmcA48IGwmhqrbM,114203
19
+ trilogy/core/models.py,sha256=Mp6MB8Gl2CZcPDWkofPX8Mym1ZvT0OUS0dKAUWCj7K8,116419
20
20
  trilogy/core/optimization.py,sha256=oM3Ry7UpbpTSm2xNkmWx70OHd2V2vWRjM72sZpsZfb8,4116
21
21
  trilogy/core/query_processor.py,sha256=clIRJ6IcsqIVBPKFsxt8bqCLsLyajvAu02MUIcKQhTo,15713
22
22
  trilogy/core/optimizations/__init__.py,sha256=pxRzNzd2g8oRMy4f_ub5va6bNS2pd4hnyp9JBzTKc1E,300
@@ -75,9 +75,9 @@ trilogy/parsing/render.py,sha256=TnLf5fg4wimpd9EvhLU-FMDwpyW9pesoedBZ0RrmWD4,118
75
75
  trilogy/parsing/trilogy.lark,sha256=1AZbQGpNmpm4KamAXA5IWcuOr2B8Gb8kUJcAOmKf_zY,10862
76
76
  trilogy/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
77
  trilogy/scripts/trilogy.py,sha256=PHxvv6f2ODv0esyyhWxlARgra8dVhqQhYl0lTrSyVNo,3729
78
- pytrilogy-0.0.1.117.dist-info/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
79
- pytrilogy-0.0.1.117.dist-info/METADATA,sha256=jrHvRWl_dtmpVu_aw08SS-whIymZ6l051tcpYmPQPD0,7878
80
- pytrilogy-0.0.1.117.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
81
- pytrilogy-0.0.1.117.dist-info/entry_points.txt,sha256=0petKryjvvtEfTlbZC1AuMFumH_WQ9v8A19LvoS6G6c,54
82
- pytrilogy-0.0.1.117.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
83
- pytrilogy-0.0.1.117.dist-info/RECORD,,
78
+ pytrilogy-0.0.1.118.dist-info/LICENSE.md,sha256=5ZRvtTyCCFwz1THxDTjAu3Lidds9WjPvvzgVwPSYNDo,1042
79
+ pytrilogy-0.0.1.118.dist-info/METADATA,sha256=tZ1kQcOTJ5JTYb5tqlfdo7g-o94TC0tKmcdqLtJ35bI,7878
80
+ pytrilogy-0.0.1.118.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
81
+ pytrilogy-0.0.1.118.dist-info/entry_points.txt,sha256=0petKryjvvtEfTlbZC1AuMFumH_WQ9v8A19LvoS6G6c,54
82
+ pytrilogy-0.0.1.118.dist-info/top_level.txt,sha256=cAy__NW_eMAa_yT9UnUNlZLFfxcg6eimUAZ184cdNiE,8
83
+ pytrilogy-0.0.1.118.dist-info/RECORD,,
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.117"
7
+ __version__ = "0.0.1.118"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
trilogy/core/functions.py CHANGED
@@ -52,12 +52,22 @@ def argument_to_purpose(arg) -> Purpose:
52
52
  if isinstance(arg, Function):
53
53
  return arg.output_purpose
54
54
  elif isinstance(arg, AggregateWrapper):
55
+ base = arg.function.output_purpose
56
+ if arg.by and base == Purpose.METRIC:
57
+ return Purpose.PROPERTY
55
58
  return arg.function.output_purpose
56
59
  elif isinstance(arg, Parenthetical):
57
60
  return argument_to_purpose(arg.content)
58
61
  elif isinstance(arg, WindowItem):
59
62
  return Purpose.PROPERTY
60
63
  elif isinstance(arg, Concept):
64
+ base = arg.purpose
65
+ if (
66
+ isinstance(arg.lineage, AggregateWrapper)
67
+ and arg.lineage.by
68
+ and base == Purpose.METRIC
69
+ ):
70
+ return Purpose.PROPERTY
61
71
  return arg.purpose
62
72
  elif isinstance(arg, (int, float, str, bool, list, NumericType, DataType)):
63
73
  return Purpose.CONSTANT
trilogy/core/models.py CHANGED
@@ -149,6 +149,11 @@ class SelectGrain(ABC):
149
149
  raise NotImplementedError
150
150
 
151
151
 
152
+ class ConstantInlineable(ABC):
153
+ def inline_concept(self, concept: Concept):
154
+ raise NotImplementedError
155
+
156
+
152
157
  class DataType(Enum):
153
158
  # PRIMITIVES
154
159
  STRING = "string"
@@ -2075,6 +2080,9 @@ class CTE(BaseModel):
2075
2080
  if concept.address in self.source_map:
2076
2081
  removed = removed.union(self.source_map[concept.address])
2077
2082
  del self.source_map[concept.address]
2083
+
2084
+ if self.condition:
2085
+ self.condition = self.condition.inline_constant(concept)
2078
2086
  # if we've entirely removed the need to join to someplace to get the concept
2079
2087
  # drop the join as well.
2080
2088
  for removed_cte in removed:
@@ -2763,7 +2771,7 @@ class LazyEnvironment(Environment):
2763
2771
  return super().__getattribute__(name)
2764
2772
 
2765
2773
 
2766
- class Comparison(ConceptArgs, Namespaced, SelectGrain, BaseModel):
2774
+ class Comparison(ConceptArgs, Namespaced, ConstantInlineable, SelectGrain, BaseModel):
2767
2775
  left: Union[
2768
2776
  int,
2769
2777
  str,
@@ -2825,6 +2833,32 @@ class Comparison(ConceptArgs, Namespaced, SelectGrain, BaseModel):
2825
2833
  def __str__(self):
2826
2834
  return self.__repr__()
2827
2835
 
2836
+ def inline_constant(self, constant: Concept) -> "Comparison":
2837
+ assert isinstance(constant.lineage, Function)
2838
+ new_val = constant.lineage.arguments[0]
2839
+ if isinstance(self.left, ConstantInlineable):
2840
+ new_left = self.left.inline_constant(constant)
2841
+ elif self.left == constant:
2842
+ new_left = new_val
2843
+ else:
2844
+ new_left = self.left
2845
+
2846
+ if isinstance(self.right, ConstantInlineable):
2847
+ new_right = self.right.inline_constant(constant)
2848
+ elif self.right == constant:
2849
+ new_right = new_val
2850
+ else:
2851
+ new_right = self.right
2852
+
2853
+ if self.right == constant:
2854
+ new_right = new_val
2855
+
2856
+ return Comparison(
2857
+ left=new_left,
2858
+ right=new_right,
2859
+ operator=self.operator,
2860
+ )
2861
+
2828
2862
  def with_namespace(self, namespace: str):
2829
2863
  return self.__class__(
2830
2864
  left=(
@@ -3001,7 +3035,7 @@ class CaseElse(Namespaced, SelectGrain, BaseModel):
3001
3035
  )
3002
3036
 
3003
3037
 
3004
- class Conditional(ConceptArgs, Namespaced, SelectGrain, BaseModel):
3038
+ class Conditional(ConceptArgs, Namespaced, ConstantInlineable, SelectGrain, BaseModel):
3005
3039
  left: Union[
3006
3040
  int,
3007
3041
  str,
@@ -3047,6 +3081,32 @@ class Conditional(ConceptArgs, Namespaced, SelectGrain, BaseModel):
3047
3081
  def __repr__(self):
3048
3082
  return f"{str(self.left)} {self.operator.value} {str(self.right)}"
3049
3083
 
3084
+ def inline_constant(self, constant: Concept) -> "Conditional":
3085
+ assert isinstance(constant.lineage, Function)
3086
+ new_val = constant.lineage.arguments[0]
3087
+ if isinstance(self.left, ConstantInlineable):
3088
+ new_left = self.left.inline_constant(constant)
3089
+ elif self.left == constant:
3090
+ new_left = new_val
3091
+ else:
3092
+ new_left = self.left
3093
+
3094
+ if isinstance(self.right, ConstantInlineable):
3095
+ new_right = self.right.inline_constant(constant)
3096
+ elif self.right == constant:
3097
+ new_right = new_val
3098
+ else:
3099
+ new_right = self.right
3100
+
3101
+ if self.right == constant:
3102
+ new_right = new_val
3103
+
3104
+ return Conditional(
3105
+ left=new_left,
3106
+ right=new_right,
3107
+ operator=self.operator,
3108
+ )
3109
+
3050
3110
  def with_namespace(self, namespace: str):
3051
3111
  return Conditional(
3052
3112
  left=(
@@ -3386,7 +3446,9 @@ class RowsetItem(Namespaced, BaseModel):
3386
3446
  return [self.content]
3387
3447
 
3388
3448
 
3389
- class Parenthetical(ConceptArgs, Namespaced, SelectGrain, BaseModel):
3449
+ class Parenthetical(
3450
+ ConceptArgs, Namespaced, ConstantInlineable, SelectGrain, BaseModel
3451
+ ):
3390
3452
  content: "Expr"
3391
3453
 
3392
3454
  def __str__(self):
@@ -3420,6 +3482,15 @@ class Parenthetical(ConceptArgs, Namespaced, SelectGrain, BaseModel):
3420
3482
  )
3421
3483
  )
3422
3484
 
3485
+ def inline_constant(self, concept: Concept):
3486
+ return Parenthetical(
3487
+ content=(
3488
+ self.content.inline_constant(concept)
3489
+ if isinstance(self.content, ConstantInlineable)
3490
+ else self.content
3491
+ )
3492
+ )
3493
+
3423
3494
  @property
3424
3495
  def concept_arguments(self) -> List[Concept]:
3425
3496
  base: List[Concept] = []
trilogy/executor.py CHANGED
@@ -16,6 +16,8 @@ from trilogy.core.models import (
16
16
  PersistStatement,
17
17
  ShowStatement,
18
18
  Concept,
19
+ ConceptDeclarationStatement,
20
+ Datasource,
19
21
  )
20
22
  from trilogy.dialect.base import BaseDialect
21
23
  from trilogy.dialect.enums import Dialects
@@ -100,6 +102,33 @@ class Executor(object):
100
102
  def execute_query(self, query) -> CursorResult:
101
103
  raise NotImplementedError("Cannot execute type {}".format(type(query)))
102
104
 
105
+ @execute_query.register
106
+ def _(self, query: ConceptDeclarationStatement) -> CursorResult:
107
+ concept = query.concept
108
+ return MockResult(
109
+ [
110
+ {
111
+ "address": concept.address,
112
+ "type": concept.datatype.value,
113
+ "purpose": concept.purpose.value,
114
+ "derivation": concept.derivation.value,
115
+ }
116
+ ],
117
+ ["address", "type", "purpose", "derivation"],
118
+ )
119
+
120
+ @execute_query.register
121
+ def _(self, query: Datasource) -> CursorResult:
122
+
123
+ return MockResult(
124
+ [
125
+ {
126
+ "name": query.name,
127
+ }
128
+ ],
129
+ ["name"],
130
+ )
131
+
103
132
  @execute_query.register
104
133
  def _(self, query: SelectStatement) -> CursorResult:
105
134
  sql = self.generator.generate_queries(