pytrilogy 0.0.3.41__tar.gz → 0.0.3.42__tar.gz

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 (140) hide show
  1. {pytrilogy-0.0.3.41/pytrilogy.egg-info → pytrilogy-0.0.3.42}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/pytrilogy.egg-info/SOURCES.txt +1 -0
  4. pytrilogy-0.0.3.42/tests/test_failure.py +47 -0
  5. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/__init__.py +1 -1
  6. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/models/build.py +13 -16
  7. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/concept_strategies_v3.py +3 -2
  8. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/group_to_node.py +23 -8
  9. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/parsing/common.py +7 -1
  10. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/parsing/parse_engine.py +1 -16
  11. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/LICENSE.md +0 -0
  12. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/README.md +0 -0
  13. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/pyproject.toml +0 -0
  14. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/pytrilogy.egg-info/dependency_links.txt +0 -0
  15. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/pytrilogy.egg-info/entry_points.txt +0 -0
  16. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/pytrilogy.egg-info/requires.txt +0 -0
  17. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/pytrilogy.egg-info/top_level.txt +0 -0
  18. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/setup.cfg +0 -0
  19. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/setup.py +0 -0
  20. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_datatypes.py +0 -0
  21. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_declarations.py +0 -0
  22. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_derived_concepts.py +0 -0
  23. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_discovery_nodes.py +0 -0
  24. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_enums.py +0 -0
  25. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_environment.py +0 -0
  26. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_executor.py +0 -0
  27. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_functions.py +0 -0
  28. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_imports.py +0 -0
  29. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_metadata.py +0 -0
  30. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_models.py +0 -0
  31. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_multi_join_assignments.py +0 -0
  32. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_parse_engine.py +0 -0
  33. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_parsing.py +0 -0
  34. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_partial_handling.py +0 -0
  35. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_query_processing.py +0 -0
  36. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_query_render.py +0 -0
  37. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_select.py +0 -0
  38. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_show.py +0 -0
  39. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_statements.py +0 -0
  40. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_typing.py +0 -0
  41. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_undefined_concept.py +0 -0
  42. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_user_functions.py +0 -0
  43. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/tests/test_where_clause.py +0 -0
  44. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/authoring/__init__.py +0 -0
  45. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/compiler.py +0 -0
  46. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/constants.py +0 -0
  47. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/__init__.py +0 -0
  48. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/constants.py +0 -0
  49. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/enums.py +0 -0
  50. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/env_processor.py +0 -0
  51. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/environment_helpers.py +0 -0
  52. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/ergonomics.py +0 -0
  53. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/exceptions.py +0 -0
  54. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/functions.py +0 -0
  55. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/graph_models.py +0 -0
  56. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/internal.py +0 -0
  57. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/models/__init__.py +0 -0
  58. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/models/author.py +0 -0
  59. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/models/build_environment.py +0 -0
  60. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/models/core.py +0 -0
  61. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/models/datasource.py +0 -0
  62. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/models/environment.py +0 -0
  63. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/models/execute.py +0 -0
  64. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/optimization.py +0 -0
  65. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/optimizations/__init__.py +0 -0
  66. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/optimizations/base_optimization.py +0 -0
  67. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/optimizations/inline_constant.py +0 -0
  68. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/optimizations/inline_datasource.py +0 -0
  69. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  70. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/__init__.py +0 -0
  71. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/graph_utils.py +0 -0
  72. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/__init__.py +0 -0
  73. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  74. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/common.py +0 -0
  75. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  76. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/group_node.py +0 -0
  77. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  78. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  79. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  80. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
  81. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
  82. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
  83. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/select_node.py +0 -0
  84. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
  85. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/union_node.py +0 -0
  86. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  87. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/node_generators/window_node.py +0 -0
  88. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/nodes/__init__.py +0 -0
  89. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/nodes/base_node.py +0 -0
  90. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/nodes/filter_node.py +0 -0
  91. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/nodes/group_node.py +0 -0
  92. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/nodes/merge_node.py +0 -0
  93. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  94. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/nodes/union_node.py +0 -0
  95. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  96. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/nodes/window_node.py +0 -0
  97. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/processing/utility.py +0 -0
  98. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/query_processor.py +0 -0
  99. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/statements/__init__.py +0 -0
  100. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/statements/author.py +0 -0
  101. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/statements/build.py +0 -0
  102. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/statements/common.py +0 -0
  103. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/core/statements/execute.py +0 -0
  104. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/__init__.py +0 -0
  105. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/base.py +0 -0
  106. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/bigquery.py +0 -0
  107. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/common.py +0 -0
  108. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/config.py +0 -0
  109. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/dataframe.py +0 -0
  110. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/duckdb.py +0 -0
  111. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/enums.py +0 -0
  112. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/postgres.py +0 -0
  113. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/presto.py +0 -0
  114. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/snowflake.py +0 -0
  115. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/dialect/sql_server.py +0 -0
  116. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/engine.py +0 -0
  117. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/executor.py +0 -0
  118. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/hooks/__init__.py +0 -0
  119. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/hooks/base_hook.py +0 -0
  120. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/hooks/graph_hook.py +0 -0
  121. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/hooks/query_debugger.py +0 -0
  122. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/metadata/__init__.py +0 -0
  123. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/parser.py +0 -0
  124. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/parsing/__init__.py +0 -0
  125. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/parsing/config.py +0 -0
  126. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/parsing/exceptions.py +0 -0
  127. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/parsing/helpers.py +0 -0
  128. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/parsing/render.py +0 -0
  129. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/parsing/trilogy.lark +0 -0
  130. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/py.typed +0 -0
  131. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/render.py +0 -0
  132. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/scripts/__init__.py +0 -0
  133. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/scripts/trilogy.py +0 -0
  134. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/std/__init__.py +0 -0
  135. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/std/date.preql +0 -0
  136. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/std/display.preql +0 -0
  137. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/std/geography.preql +0 -0
  138. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/std/money.preql +0 -0
  139. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/std/report.preql +0 -0
  140. {pytrilogy-0.0.3.41 → pytrilogy-0.0.3.42}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytrilogy
3
- Version: 0.0.3.41
3
+ Version: 0.0.3.42
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytrilogy
3
- Version: 0.0.3.41
3
+ Version: 0.0.3.42
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -15,6 +15,7 @@ tests/test_discovery_nodes.py
15
15
  tests/test_enums.py
16
16
  tests/test_environment.py
17
17
  tests/test_executor.py
18
+ tests/test_failure.py
18
19
  tests/test_functions.py
19
20
  tests/test_imports.py
20
21
  tests/test_metadata.py
@@ -0,0 +1,47 @@
1
+ from pytest import raises
2
+
3
+ from trilogy import Dialects
4
+ from trilogy.core.exceptions import UnresolvableQueryException
5
+
6
+
7
+ def test_cannot_find():
8
+ x = Dialects.DUCK_DB.default_executor()
9
+
10
+ with raises(UnresolvableQueryException):
11
+ x.generate_sql(
12
+ """
13
+ key x int;
14
+ key y int;
15
+
16
+ datasource fun (
17
+ y: y,
18
+ )
19
+ address abc;
20
+
21
+
22
+ select x;
23
+
24
+ """
25
+ )
26
+
27
+
28
+ def test_cannot_find_complex():
29
+ x = Dialects.DUCK_DB.default_executor()
30
+ with raises(UnresolvableQueryException):
31
+ x.generate_sql(
32
+ """
33
+ key x int;
34
+ key y int;
35
+
36
+ auto sum <- x+y;
37
+
38
+ datasource fun (
39
+ y: y,
40
+ )
41
+ address abc;
42
+
43
+
44
+ select sum(y) by x as fun;
45
+
46
+ """
47
+ )
@@ -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.41"
7
+ __version__ = "0.0.3.42"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -1541,18 +1541,14 @@ class Factory:
1541
1541
  else:
1542
1542
  # constants, etc, can be ignored for group
1543
1543
  continue
1544
- group_base = group_base.model_copy(
1545
- deep=True,
1546
- update={
1547
- "lineage": AggregateWrapper(
1548
- function=group_base.lineage.function,
1549
- by=final_args,
1550
- )
1551
- },
1552
- )
1553
- group_base = group_base.with_grain(
1554
- Grain.from_concepts(final_args, environment=self.environment)
1544
+ group_base = arbitrary_to_concept(
1545
+ AggregateWrapper(
1546
+ function=group_base.lineage.function,
1547
+ by=final_args,
1548
+ ),
1549
+ environment=self.environment,
1555
1550
  )
1551
+
1556
1552
  rval = self.build(group_base)
1557
1553
  return BuildFunction.model_construct(
1558
1554
  operator=base.operator,
@@ -1650,21 +1646,20 @@ class Factory:
1650
1646
  ]
1651
1647
  else:
1652
1648
  by = [self.build(x) for x in base.by]
1649
+
1653
1650
  parent = self.build(base.function)
1654
1651
  return BuildAggregateWrapper.model_construct(function=parent, by=by)
1655
1652
 
1656
1653
  @build.register
1657
1654
  def _(self, base: ColumnAssignment) -> BuildColumnAssignment:
1658
-
1655
+ fetched = self.environment.concepts[base.concept.address]
1659
1656
  return BuildColumnAssignment.model_construct(
1660
1657
  alias=(
1661
1658
  self.build(base.alias)
1662
1659
  if isinstance(base.alias, Function)
1663
1660
  else base.alias
1664
1661
  ),
1665
- concept=self.build(
1666
- self.environment.concepts[base.concept.address].with_grain(self.grain)
1667
- ),
1662
+ concept=self.build(fetched.with_grain(self.grain)),
1668
1663
  modifiers=base.modifiers,
1669
1664
  )
1670
1665
 
@@ -1683,7 +1678,9 @@ class Factory:
1683
1678
  from trilogy.parsing.common import arbitrary_to_concept
1684
1679
 
1685
1680
  bexpr: Any
1686
- if isinstance(base.expr, AggregateWrapper):
1681
+ if isinstance(base.expr, (AggregateWrapper, WindowItem, FilterItem)) or (
1682
+ isinstance(base.expr, Function) and base.expr.operator == FunctionType.GROUP
1683
+ ):
1687
1684
  bexpr = arbitrary_to_concept(
1688
1685
  base.expr,
1689
1686
  environment=self.environment,
@@ -5,6 +5,7 @@ from typing import List, Optional, Protocol, Union
5
5
  from trilogy.constants import logger
6
6
  from trilogy.core.enums import Derivation, FunctionType, Granularity
7
7
  from trilogy.core.env_processor import generate_graph
8
+ from trilogy.core.exceptions import UnresolvableQueryException
8
9
  from trilogy.core.graph_models import ReferenceGraph
9
10
  from trilogy.core.models.author import (
10
11
  UndefinedConcept,
@@ -1120,8 +1121,8 @@ def source_query_concepts(
1120
1121
  error_strings = [
1121
1122
  f"{c.address}<{c.purpose}>{c.derivation}>" for c in output_concepts
1122
1123
  ]
1123
- raise ValueError(
1124
- f"Could not resolve connections between {error_strings} from environment graph."
1124
+ raise UnresolvableQueryException(
1125
+ f"Could not resolve connections for query with output {error_strings} from current model."
1125
1126
  )
1126
1127
  final = [x for x in root.output_concepts if x.address not in root.hidden_concepts]
1127
1128
  logger.info(
@@ -31,9 +31,9 @@ def gen_group_to_node(
31
31
  raise SyntaxError(
32
32
  f"Group to should have function lineage, is {type(concept.lineage)}"
33
33
  )
34
- group_arg = concept.lineage.arguments[0]
35
34
 
36
35
  parent_concepts: List[BuildConcept] = concept.lineage.concept_arguments
36
+ root = parent_concepts[0]
37
37
  logger.info(
38
38
  f"{padding(depth)}{LOGGER_PREFIX} group by node has required parents {[x.address for x in parent_concepts]}"
39
39
  )
@@ -47,7 +47,7 @@ def gen_group_to_node(
47
47
  conditions=conditions,
48
48
  )
49
49
  ]
50
-
50
+ outputs = parent_concepts + [concept]
51
51
  group_node = GroupNode(
52
52
  output_concepts=parent_concepts + [concept],
53
53
  input_concepts=parent_concepts,
@@ -56,17 +56,30 @@ def gen_group_to_node(
56
56
  depth=depth,
57
57
  preexisting_conditions=conditions.conditional if conditions else None,
58
58
  hidden_concepts=set(
59
- [group_arg.address]
60
- if isinstance(group_arg, BuildConcept)
61
- and group_arg.address not in local_optional
62
- else []
59
+ [
60
+ x.address
61
+ for x in outputs
62
+ if x.address not in local_optional
63
+ and x.address != concept.address
64
+ and x.address != root.address
65
+ ]
63
66
  ),
64
67
  )
65
68
 
66
69
  # early exit if no optional
67
- if not local_optional:
70
+ missing_local_option: list[BuildConcept] = [
71
+ x for x in local_optional if x not in group_node.output_concepts
72
+ ]
73
+ if not missing_local_option:
74
+ logger.info(
75
+ f"{padding(depth)}{LOGGER_PREFIX} no missing local optional required, returning group node only."
76
+ )
68
77
  return group_node
69
78
 
79
+ logger.info(
80
+ f"{padding(depth)}{LOGGER_PREFIX} group by node is missing required optional {[x.address for x in missing_local_option]}"
81
+ )
82
+
70
83
  # the keys we group by
71
84
  # are what we can use for enrichment
72
85
  enrich_node = source_concepts( # this fetches the parent + join keys
@@ -83,7 +96,9 @@ def gen_group_to_node(
83
96
  f"{padding(depth)}{LOGGER_PREFIX} group by node enrich node, returning group node only."
84
97
  )
85
98
  return group_node
86
-
99
+ logger.info(
100
+ f"{padding(depth)}{LOGGER_PREFIX} returning group to node with enrichment."
101
+ )
87
102
  return MergeNode(
88
103
  input_concepts=[concept]
89
104
  + local_optional
@@ -771,7 +771,13 @@ def arbitrary_to_concept(
771
771
  )
772
772
  elif isinstance(parent, Function):
773
773
  if not name:
774
- name = f"{VIRTUAL_CONCEPT_PREFIX}_func_{parent.operator.value}_{string_to_hash(str(parent))}"
774
+ if parent.operator == FunctionType.GROUP:
775
+ name = (
776
+ f"{VIRTUAL_CONCEPT_PREFIX}_group_to_{string_to_hash(str(parent))}"
777
+ )
778
+ else:
779
+ name = f"{VIRTUAL_CONCEPT_PREFIX}_func_{parent.operator.value}_{string_to_hash(str(parent))}"
780
+
775
781
  if parent.operator == FunctionType.GROUP:
776
782
  return group_function_to_concept(
777
783
  parent,
@@ -590,6 +590,7 @@ class ParseToObjects(Transformer):
590
590
  keys=set([x.address for x in parents]),
591
591
  modifiers=modifiers,
592
592
  )
593
+
593
594
  self.environment.add_concept(concept, meta)
594
595
  return concept
595
596
 
@@ -1367,23 +1368,7 @@ class ParseToObjects(Transformer):
1367
1368
  def comparison(self, args) -> Comparison:
1368
1369
  if args[1] == ComparisonOperator.IN:
1369
1370
  raise SyntaxError
1370
- # if isinstance(args[0], AggregateWrapper):
1371
- # left_c = arbitrary_to_concept(
1372
- # args[0],
1373
- # environment=self.environment,
1374
- # )
1375
- # self.environment.add_concept(left_c)
1376
- # left = left_c.reference
1377
- # else:
1378
1371
  left = args[0]
1379
- # if isinstance(args[2], AggregateWrapper):
1380
- # right_c = arbitrary_to_concept(
1381
- # args[2],
1382
- # environment=self.environment,
1383
- # )
1384
- # self.environment.add_concept(right_c)
1385
- # right = right_c.reference
1386
- # else:
1387
1372
  right = args[2]
1388
1373
  return Comparison(left=left, right=right, operator=args[1])
1389
1374
 
File without changes
File without changes
File without changes
File without changes