pytrilogy 0.0.3.85__tar.gz → 0.0.3.86__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.85/pytrilogy.egg-info → pytrilogy-0.0.3.86}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_datatypes.py +1 -1
  4. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/__init__.py +1 -1
  5. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/models/author.py +10 -12
  6. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/duckdb.py +1 -0
  7. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/parsing/parse_engine.py +3 -1
  8. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/parsing/trilogy.lark +1 -1
  9. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/LICENSE.md +0 -0
  10. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/README.md +0 -0
  11. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/pyproject.toml +0 -0
  12. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/pytrilogy.egg-info/SOURCES.txt +0 -0
  13. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/pytrilogy.egg-info/dependency_links.txt +0 -0
  14. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/pytrilogy.egg-info/entry_points.txt +0 -0
  15. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/pytrilogy.egg-info/requires.txt +0 -0
  16. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/pytrilogy.egg-info/top_level.txt +0 -0
  17. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/setup.cfg +0 -0
  18. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/setup.py +0 -0
  19. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_declarations.py +0 -0
  20. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_derived_concepts.py +0 -0
  21. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_discovery_nodes.py +0 -0
  22. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_enums.py +0 -0
  23. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_environment.py +0 -0
  24. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_execute_models.py +0 -0
  25. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_executor.py +0 -0
  26. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_failure.py +0 -0
  27. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_functions.py +0 -0
  28. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_imports.py +0 -0
  29. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_metadata.py +0 -0
  30. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_models.py +0 -0
  31. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_multi_join_assignments.py +0 -0
  32. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_parse_engine.py +0 -0
  33. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_parsing.py +0 -0
  34. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_parsing_failures.py +0 -0
  35. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_partial_handling.py +0 -0
  36. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_query_processing.py +0 -0
  37. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_query_render.py +0 -0
  38. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_select.py +0 -0
  39. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_show.py +0 -0
  40. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_statements.py +0 -0
  41. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_typing.py +0 -0
  42. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_undefined_concept.py +0 -0
  43. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_user_functions.py +0 -0
  44. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/tests/test_where_clause.py +0 -0
  45. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/authoring/__init__.py +0 -0
  46. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/compiler.py +0 -0
  47. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/constants.py +0 -0
  48. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/__init__.py +0 -0
  49. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/constants.py +0 -0
  50. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/enums.py +0 -0
  51. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/env_processor.py +0 -0
  52. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/environment_helpers.py +0 -0
  53. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/ergonomics.py +0 -0
  54. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/exceptions.py +0 -0
  55. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/functions.py +0 -0
  56. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/graph_models.py +0 -0
  57. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/internal.py +0 -0
  58. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/models/__init__.py +0 -0
  59. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/models/build.py +0 -0
  60. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/models/build_environment.py +0 -0
  61. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/models/core.py +0 -0
  62. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/models/datasource.py +0 -0
  63. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/models/environment.py +0 -0
  64. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/models/execute.py +0 -0
  65. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/optimization.py +0 -0
  66. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/optimizations/__init__.py +0 -0
  67. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/optimizations/base_optimization.py +0 -0
  68. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/optimizations/inline_datasource.py +0 -0
  69. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  70. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/__init__.py +0 -0
  71. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/concept_strategies_v3.py +0 -0
  72. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/discovery_loop.py +0 -0
  73. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/discovery_node_factory.py +0 -0
  74. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/discovery_utility.py +0 -0
  75. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/discovery_validation.py +0 -0
  76. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/graph_utils.py +0 -0
  77. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/__init__.py +0 -0
  78. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  79. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/common.py +0 -0
  80. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/constant_node.py +0 -0
  81. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  82. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/group_node.py +0 -0
  83. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  84. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  85. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  86. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/recursive_node.py +0 -0
  87. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  88. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
  89. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
  90. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
  91. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/select_node.py +0 -0
  92. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
  93. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/union_node.py +0 -0
  94. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  95. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/node_generators/window_node.py +0 -0
  96. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/__init__.py +0 -0
  97. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/base_node.py +0 -0
  98. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/filter_node.py +0 -0
  99. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/group_node.py +0 -0
  100. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/merge_node.py +0 -0
  101. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/recursive_node.py +0 -0
  102. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  103. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/union_node.py +0 -0
  104. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  105. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/nodes/window_node.py +0 -0
  106. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/processing/utility.py +0 -0
  107. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/query_processor.py +0 -0
  108. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/statements/__init__.py +0 -0
  109. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/statements/author.py +0 -0
  110. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/statements/build.py +0 -0
  111. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/statements/common.py +0 -0
  112. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/statements/execute.py +0 -0
  113. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/core/utility.py +0 -0
  114. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/__init__.py +0 -0
  115. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/base.py +0 -0
  116. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/bigquery.py +0 -0
  117. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/common.py +0 -0
  118. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/config.py +0 -0
  119. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/dataframe.py +0 -0
  120. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/enums.py +0 -0
  121. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/postgres.py +0 -0
  122. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/presto.py +0 -0
  123. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/snowflake.py +0 -0
  124. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/dialect/sql_server.py +0 -0
  125. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/engine.py +0 -0
  126. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/executor.py +0 -0
  127. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/hooks/__init__.py +0 -0
  128. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/hooks/base_hook.py +0 -0
  129. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/hooks/graph_hook.py +0 -0
  130. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/hooks/query_debugger.py +0 -0
  131. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/metadata/__init__.py +0 -0
  132. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/parser.py +0 -0
  133. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/parsing/__init__.py +0 -0
  134. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/parsing/common.py +0 -0
  135. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/parsing/config.py +0 -0
  136. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/parsing/exceptions.py +0 -0
  137. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/parsing/helpers.py +0 -0
  138. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/parsing/render.py +0 -0
  139. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/py.typed +0 -0
  140. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/render.py +0 -0
  141. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/scripts/__init__.py +0 -0
  142. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/scripts/trilogy.py +0 -0
  143. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/std/__init__.py +0 -0
  144. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/std/date.preql +0 -0
  145. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/std/display.preql +0 -0
  146. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/std/geography.preql +0 -0
  147. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/std/money.preql +0 -0
  148. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/std/net.preql +0 -0
  149. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/std/ranking.preql +0 -0
  150. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/std/report.preql +0 -0
  151. {pytrilogy-0.0.3.85 → pytrilogy-0.0.3.86}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytrilogy
3
- Version: 0.0.3.85
3
+ Version: 0.0.3.86
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.85
3
+ Version: 0.0.3.86
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -30,7 +30,7 @@ def test_cast_error():
30
30
  """
31
31
  )
32
32
  except InvalidSyntaxException as e:
33
- assert "Cannot compare DataType.INTEGER and DataType.STRING" in str(e)
33
+ assert "Cannot compare INTEGER (ref:local.x) and STRING (ref:local.y)" in str(e)
34
34
  found = True
35
35
  if not found:
36
36
  assert False, "Expected InvalidSyntaxException not raised"
@@ -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.85"
7
+ __version__ = "0.0.3.86"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -637,33 +637,31 @@ class Comparison(ConceptArgs, Mergeable, DataTyped, Namespaced, BaseModel):
637
637
 
638
638
  @model_validator(mode="after")
639
639
  def validate_comparison(self):
640
+ left_type = arg_to_datatype(self.left)
641
+ right_type = arg_to_datatype(self.right)
640
642
  if self.operator in (ComparisonOperator.IS, ComparisonOperator.IS_NOT):
641
- if self.right != MagicConstants.NULL and DataType.BOOL != arg_to_datatype(
642
- self.right
643
- ):
643
+ if self.right != MagicConstants.NULL and DataType.BOOL != right_type:
644
644
  raise SyntaxError(
645
645
  f"Cannot use {self.operator.value} with non-null or boolean value {self.right}"
646
646
  )
647
647
  elif self.operator in (ComparisonOperator.IN, ComparisonOperator.NOT_IN):
648
- right_type = arg_to_datatype(self.right)
648
+
649
649
  if isinstance(right_type, ArrayType) and not is_compatible_datatype(
650
- arg_to_datatype(self.left), right_type.value_data_type
650
+ left_type, right_type.value_data_type
651
651
  ):
652
652
  raise SyntaxError(
653
- f"Cannot compare {arg_to_datatype(self.left)} and {right_type} with operator {self.operator} in {str(self)}"
653
+ f"Cannot compare {left_type} and {right_type} with operator {self.operator} in {str(self)}"
654
654
  )
655
655
  elif isinstance(self.right, Concept) and not is_compatible_datatype(
656
- arg_to_datatype(self.left), arg_to_datatype(self.right)
656
+ left_type, right_type
657
657
  ):
658
658
  raise SyntaxError(
659
- f"Cannot compare {arg_to_datatype(self.left)} and {arg_to_datatype(self.right)} with operator {self.operator} in {str(self)}"
659
+ f"Cannot compare {left_type.name} and {right_type.name} with operator {self.operator} in {str(self)}"
660
660
  )
661
661
  else:
662
- if not is_compatible_datatype(
663
- arg_to_datatype(self.left), arg_to_datatype(self.right)
664
- ):
662
+ if not is_compatible_datatype(left_type, right_type):
665
663
  raise SyntaxError(
666
- f"Cannot compare {arg_to_datatype(self.left)} and {arg_to_datatype(self.right)} of different types with operator {self.operator} in {str(self)}"
664
+ f"Cannot compare {left_type.name} ({self.left}) and {right_type.name} ({self.right}) of different types with operator {self.operator.value} in {str(self)}"
667
665
  )
668
666
 
669
667
  return self
@@ -76,6 +76,7 @@ FUNCTION_MAP = {
76
76
  FunctionType.DATE: lambda x: f"cast({x[0]} as date)",
77
77
  FunctionType.DATE_TRUNCATE: lambda x: f"date_trunc('{x[1]}', {x[0]})",
78
78
  FunctionType.DATE_ADD: lambda x: f"date_add({x[0]}, {x[2]} * INTERVAL 1 {x[1]})",
79
+ FunctionType.DATE_SUB: lambda x: f"date_add({x[0]}, -{x[2]} * INTERVAL 1 {x[1]})",
79
80
  FunctionType.DATE_PART: lambda x: f"date_part('{x[1]}', {x[0]})",
80
81
  FunctionType.DATE_DIFF: lambda x: f"date_diff('{x[2]}', {x[0]}, {x[1]})",
81
82
  FunctionType.CONCAT: lambda x: f"({' || '.join(x)})",
@@ -683,7 +683,9 @@ class ParseToObjects(Transformer):
683
683
  )
684
684
  # let constant purposes exist to support round-tripping
685
685
  # as a build concept may end up with a constant based on constant inlining happening recursively
686
- if (
686
+ if purpose == Purpose.KEY and concept.purpose != Purpose.KEY:
687
+ concept.purpose = Purpose.KEY
688
+ elif (
687
689
  purpose
688
690
  and purpose != Purpose.AUTO
689
691
  and concept.purpose != purpose
@@ -367,7 +367,7 @@
367
367
  fyear: _YEAR expr ")"
368
368
 
369
369
  DATE_PART: "DAY"i | "WEEK"i | "MONTH"i | "QUARTER"i | "YEAR"i | "MINUTE"i | "HOUR"i | "SECOND"i | "DAY_OF_WEEK"i
370
- _DATE_TRUNC.1: "date_trunc("i
370
+ _DATE_TRUNC.1: "date_trunc("i | "date_truncate("i
371
371
  fdate_trunc: _DATE_TRUNC expr "," DATE_PART ")"
372
372
  _DATE_PART.1: "date_part("i
373
373
  fdate_part: _DATE_PART expr "," DATE_PART ")"
File without changes
File without changes
File without changes
File without changes