pytrilogy 0.0.3.81__tar.gz → 0.0.3.82__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 (151) hide show
  1. {pytrilogy-0.0.3.81/pytrilogy.egg-info → pytrilogy-0.0.3.82}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/pytrilogy.egg-info/SOURCES.txt +1 -0
  4. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/__init__.py +1 -1
  5. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/concept_strategies_v3.py +6 -5
  6. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/discovery_node_factory.py +17 -1
  7. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/discovery_validation.py +0 -1
  8. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/__init__.py +2 -0
  9. pytrilogy-0.0.3.82/trilogy/core/processing/node_generators/constant_node.py +38 -0
  10. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/utility.py +5 -2
  11. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/LICENSE.md +0 -0
  12. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/README.md +0 -0
  13. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/pyproject.toml +0 -0
  14. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/pytrilogy.egg-info/dependency_links.txt +0 -0
  15. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/pytrilogy.egg-info/entry_points.txt +0 -0
  16. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/pytrilogy.egg-info/requires.txt +0 -0
  17. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/pytrilogy.egg-info/top_level.txt +0 -0
  18. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/setup.cfg +0 -0
  19. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/setup.py +0 -0
  20. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_datatypes.py +0 -0
  21. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_declarations.py +0 -0
  22. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_derived_concepts.py +0 -0
  23. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_discovery_nodes.py +0 -0
  24. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_enums.py +0 -0
  25. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_environment.py +0 -0
  26. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_execute_models.py +0 -0
  27. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_executor.py +0 -0
  28. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_failure.py +0 -0
  29. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_functions.py +0 -0
  30. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_imports.py +0 -0
  31. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_metadata.py +0 -0
  32. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_models.py +0 -0
  33. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_multi_join_assignments.py +0 -0
  34. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_parse_engine.py +0 -0
  35. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_parsing.py +0 -0
  36. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_parsing_failures.py +0 -0
  37. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_partial_handling.py +0 -0
  38. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_query_processing.py +0 -0
  39. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_query_render.py +0 -0
  40. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_select.py +0 -0
  41. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_show.py +0 -0
  42. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_statements.py +0 -0
  43. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_typing.py +0 -0
  44. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_undefined_concept.py +0 -0
  45. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_user_functions.py +0 -0
  46. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/tests/test_where_clause.py +0 -0
  47. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/authoring/__init__.py +0 -0
  48. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/compiler.py +0 -0
  49. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/constants.py +0 -0
  50. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/__init__.py +0 -0
  51. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/constants.py +0 -0
  52. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/enums.py +0 -0
  53. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/env_processor.py +0 -0
  54. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/environment_helpers.py +0 -0
  55. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/ergonomics.py +0 -0
  56. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/exceptions.py +0 -0
  57. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/functions.py +0 -0
  58. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/graph_models.py +0 -0
  59. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/internal.py +0 -0
  60. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/models/__init__.py +0 -0
  61. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/models/author.py +0 -0
  62. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/models/build.py +0 -0
  63. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/models/build_environment.py +0 -0
  64. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/models/core.py +0 -0
  65. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/models/datasource.py +0 -0
  66. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/models/environment.py +0 -0
  67. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/models/execute.py +0 -0
  68. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/optimization.py +0 -0
  69. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/optimizations/__init__.py +0 -0
  70. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/optimizations/base_optimization.py +0 -0
  71. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/optimizations/inline_datasource.py +0 -0
  72. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  73. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/__init__.py +0 -0
  74. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/discovery_loop.py +0 -0
  75. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/discovery_utility.py +1 -1
  76. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/graph_utils.py +0 -0
  77. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  78. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/common.py +0 -0
  79. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  80. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/group_node.py +0 -0
  81. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  82. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  83. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  84. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/recursive_node.py +0 -0
  85. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  86. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
  87. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
  88. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
  89. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/select_node.py +0 -0
  90. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
  91. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/union_node.py +0 -0
  92. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  93. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/node_generators/window_node.py +0 -0
  94. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/nodes/__init__.py +0 -0
  95. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/nodes/base_node.py +0 -0
  96. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/nodes/filter_node.py +0 -0
  97. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/nodes/group_node.py +0 -0
  98. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/nodes/merge_node.py +0 -0
  99. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/nodes/recursive_node.py +0 -0
  100. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  101. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/nodes/union_node.py +0 -0
  102. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  103. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/processing/nodes/window_node.py +0 -0
  104. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/query_processor.py +0 -0
  105. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/statements/__init__.py +0 -0
  106. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/statements/author.py +0 -0
  107. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/statements/build.py +0 -0
  108. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/statements/common.py +0 -0
  109. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/statements/execute.py +0 -0
  110. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/core/utility.py +0 -0
  111. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/__init__.py +0 -0
  112. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/base.py +0 -0
  113. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/bigquery.py +0 -0
  114. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/common.py +0 -0
  115. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/config.py +0 -0
  116. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/dataframe.py +0 -0
  117. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/duckdb.py +0 -0
  118. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/enums.py +0 -0
  119. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/postgres.py +0 -0
  120. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/presto.py +0 -0
  121. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/snowflake.py +0 -0
  122. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/dialect/sql_server.py +0 -0
  123. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/engine.py +0 -0
  124. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/executor.py +0 -0
  125. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/hooks/__init__.py +0 -0
  126. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/hooks/base_hook.py +0 -0
  127. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/hooks/graph_hook.py +0 -0
  128. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/hooks/query_debugger.py +0 -0
  129. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/metadata/__init__.py +0 -0
  130. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/parser.py +0 -0
  131. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/parsing/__init__.py +0 -0
  132. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/parsing/common.py +0 -0
  133. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/parsing/config.py +0 -0
  134. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/parsing/exceptions.py +0 -0
  135. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/parsing/helpers.py +0 -0
  136. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/parsing/parse_engine.py +0 -0
  137. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/parsing/render.py +0 -0
  138. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/parsing/trilogy.lark +0 -0
  139. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/py.typed +0 -0
  140. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/render.py +0 -0
  141. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/scripts/__init__.py +0 -0
  142. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/scripts/trilogy.py +0 -0
  143. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/std/__init__.py +0 -0
  144. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/std/date.preql +0 -0
  145. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/std/display.preql +0 -0
  146. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/std/geography.preql +0 -0
  147. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/std/money.preql +0 -0
  148. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/std/net.preql +0 -0
  149. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/std/ranking.preql +0 -0
  150. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/std/report.preql +0 -0
  151. {pytrilogy-0.0.3.81 → pytrilogy-0.0.3.82}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytrilogy
3
- Version: 0.0.3.81
3
+ Version: 0.0.3.82
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.81
3
+ Version: 0.0.3.82
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -81,6 +81,7 @@ trilogy/core/processing/utility.py
81
81
  trilogy/core/processing/node_generators/__init__.py
82
82
  trilogy/core/processing/node_generators/basic_node.py
83
83
  trilogy/core/processing/node_generators/common.py
84
+ trilogy/core/processing/node_generators/constant_node.py
84
85
  trilogy/core/processing/node_generators/filter_node.py
85
86
  trilogy/core/processing/node_generators/group_node.py
86
87
  trilogy/core/processing/node_generators/group_to_node.py
@@ -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.81"
7
+ __version__ = "0.0.3.82"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -63,6 +63,11 @@ def generate_candidates_restrictive(
63
63
  and x.address not in priority_concept.pseudonyms
64
64
  and priority_concept.address not in x.pseudonyms
65
65
  ]
66
+
67
+ # if it's single row, joins are irrelevant. Fetch without keys.
68
+ if priority_concept.granularity == Granularity.SINGLE_ROW:
69
+ return [], conditions
70
+
66
71
  if conditions and priority_concept.derivation in ROOT_DERIVATIONS:
67
72
  logger.info(
68
73
  f"{depth_to_prefix(depth)}{LOGGER_PREFIX} Injecting additional conditional row arguments as all remaining concepts are roots or constant"
@@ -72,9 +77,6 @@ def generate_candidates_restrictive(
72
77
  unique(list(conditions.row_arguments) + local_candidates, "address"),
73
78
  None,
74
79
  )
75
- # if it's single row, joins are irrelevant. Fetch without keys.
76
- if priority_concept.granularity == Granularity.SINGLE_ROW:
77
- return [], conditions
78
80
 
79
81
  return local_candidates, conditions
80
82
 
@@ -324,7 +326,6 @@ def check_for_early_exit(
324
326
  f"{depth_to_prefix(context.depth)}{LOGGER_PREFIX} Not complete (missing {missing}), continuing search"
325
327
  )
326
328
  # if we have attempted on root node, we've tried them all.
327
- # inject in another search with filter concepts
328
329
  if priority_concept.derivation == Derivation.ROOT:
329
330
  logger.info(
330
331
  f"{depth_to_prefix(context.depth)}{LOGGER_PREFIX} Breaking as attempted root with no results"
@@ -364,7 +365,7 @@ def generate_loop_completion(context: LoopContext, virtual: set[str]) -> Strateg
364
365
  for x in context.stack
365
366
  }
366
367
  logger.info(
367
- f"Condition {context.conditions} not required, parents included filtering! {parent_map }"
368
+ f"Condition {context.conditions} not required, parents included filtering! {parent_map}"
368
369
  )
369
370
  if len(context.stack) == 1:
370
371
  output: StrategyNode = context.stack[0]
@@ -12,6 +12,7 @@ from trilogy.core.models.build_environment import BuildEnvironment
12
12
  from trilogy.core.processing.discovery_utility import LOGGER_PREFIX, depth_to_prefix
13
13
  from trilogy.core.processing.node_generators import (
14
14
  gen_basic_node,
15
+ gen_constant_node,
15
16
  gen_filter_node,
16
17
  gen_group_node,
17
18
  gen_group_to_node,
@@ -252,6 +253,21 @@ def _generate_basic_node(ctx: NodeGenerationContext) -> StrategyNode | None:
252
253
  )
253
254
 
254
255
 
256
+ def _generate_constant_node(ctx: NodeGenerationContext) -> StrategyNode | None:
257
+ ctx.log_generation("constant")
258
+ return gen_constant_node(
259
+ ctx.concept,
260
+ ctx.local_optional,
261
+ history=ctx.history,
262
+ environment=ctx.environment,
263
+ g=ctx.g,
264
+ depth=ctx.next_depth,
265
+ source_concepts=ctx.source_concepts,
266
+ conditions=ctx.conditions,
267
+ accept_partial=ctx.accept_partial,
268
+ )
269
+
270
+
255
271
  class RootNodeHandler:
256
272
  """Handles complex root node generation logic."""
257
273
 
@@ -469,7 +485,7 @@ def generate_node(
469
485
  Derivation.GROUP_TO: lambda: _generate_group_to_node(context),
470
486
  Derivation.BASIC: lambda: _generate_basic_node(context),
471
487
  Derivation.ROOT: lambda: RootNodeHandler(context).generate(),
472
- Derivation.CONSTANT: lambda: RootNodeHandler(context).generate(),
488
+ Derivation.CONSTANT: lambda: _generate_constant_node(context),
473
489
  }
474
490
 
475
491
  handler = derivation_handlers.get(concept.derivation)
@@ -105,7 +105,6 @@ def validate_stack(
105
105
 
106
106
  for concept in resolved.output_concepts:
107
107
  if concept.address in resolved.hidden_concepts:
108
-
109
108
  continue
110
109
 
111
110
  validate_concept(
@@ -1,4 +1,5 @@
1
1
  from .basic_node import gen_basic_node
2
+ from .constant_node import gen_constant_node
2
3
  from .filter_node import gen_filter_node
3
4
  from .group_node import gen_group_node
4
5
  from .group_to_node import gen_group_to_node
@@ -26,4 +27,5 @@ __all__ = [
26
27
  "gen_multiselect_node",
27
28
  "gen_synonym_node",
28
29
  "gen_recursive_node",
30
+ "gen_constant_node",
29
31
  ]
@@ -0,0 +1,38 @@
1
+ from typing import List
2
+
3
+ from trilogy.core.models.build import BuildConcept, BuildWhereClause
4
+ from trilogy.core.models.build_environment import BuildEnvironment
5
+ from trilogy.core.processing.nodes import History, StrategyNode
6
+
7
+ LOGGER_PREFIX = "[GEN_CONSTANT_NODE]"
8
+
9
+
10
+ def gen_constant_node(
11
+ concept: BuildConcept,
12
+ local_optional: List[BuildConcept],
13
+ environment: BuildEnvironment,
14
+ g,
15
+ depth: int,
16
+ source_concepts,
17
+ history: History | None = None,
18
+ conditions: BuildWhereClause | None = None,
19
+ accept_partial: bool = False,
20
+ ):
21
+ """our only goal here is to generate a row if conditions exist, or none if they do not"""
22
+
23
+ targets = [concept] + local_optional
24
+ if conditions:
25
+ targets += conditions.row_arguments
26
+ parent_node: StrategyNode | None = source_concepts(
27
+ mandatory_list=targets,
28
+ environment=environment,
29
+ g=g,
30
+ depth=depth + 1,
31
+ history=history,
32
+ conditions=conditions,
33
+ accept_partial=accept_partial,
34
+ )
35
+ if not parent_node:
36
+ return None
37
+ parent_node.set_output_concepts([concept] + local_optional)
38
+ return parent_node
@@ -10,6 +10,7 @@ from trilogy.constants import MagicConstants
10
10
  from trilogy.core.enums import (
11
11
  BooleanOperator,
12
12
  DatePart,
13
+ Derivation,
13
14
  FunctionClass,
14
15
  Granularity,
15
16
  JoinType,
@@ -262,16 +263,19 @@ def calculate_graph_relevance(
262
263
  """
263
264
  relevance = 0
264
265
  for node in g.nodes:
266
+
265
267
  if node not in subset_nodes:
266
268
  continue
267
269
  if not g.nodes[node]["type"] == NodeType.CONCEPT:
268
270
  continue
269
271
  concept = [x for x in concepts if x.address == node].pop()
270
-
272
+ # debug granularity and derivation
271
273
  # a single row concept can always be crossjoined
272
274
  # therefore a graph with only single row concepts is always relevant
273
275
  if concept.granularity == Granularity.SINGLE_ROW:
274
276
  continue
277
+ if concept.derivation == Derivation.CONSTANT:
278
+ continue
275
279
  # if it's an aggregate up to an arbitrary grain, it can be joined in later
276
280
  # and can be ignored in subgraph
277
281
  if concept.purpose == Purpose.METRIC:
@@ -284,7 +288,6 @@ def calculate_graph_relevance(
284
288
  continue
285
289
  # Added 2023-10-18 since we seemed to be strangely dropping things
286
290
  relevance += 1
287
-
288
291
  return relevance
289
292
 
290
293
 
File without changes
File without changes
File without changes
File without changes
@@ -73,11 +73,11 @@ def get_priority_concept(
73
73
  + [c for c in remaining_concept if c.derivation == Derivation.RECURSIVE]
74
74
  + [c for c in remaining_concept if c.derivation == Derivation.BASIC]
75
75
  + [c for c in remaining_concept if c.derivation == Derivation.GROUP_TO]
76
+ + [c for c in remaining_concept if c.derivation == Derivation.CONSTANT]
76
77
  # finally our plain selects
77
78
  + [
78
79
  c for c in remaining_concept if c.derivation == Derivation.ROOT
79
80
  ] # and any non-single row constants
80
- + [c for c in remaining_concept if c.derivation == Derivation.CONSTANT]
81
81
  )
82
82
 
83
83
  priority += [