pytrilogy 0.0.3.42__tar.gz → 0.0.3.43__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 (141) hide show
  1. {pytrilogy-0.0.3.42/pytrilogy.egg-info → pytrilogy-0.0.3.43}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/pytrilogy.egg-info/SOURCES.txt +1 -0
  4. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_parsing.py +1 -101
  5. pytrilogy-0.0.3.43/tests/test_parsing_failures.py +142 -0
  6. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/__init__.py +1 -1
  7. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/window_node.py +9 -1
  8. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/bigquery.py +1 -1
  9. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/parsing/parse_engine.py +23 -6
  10. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/LICENSE.md +0 -0
  11. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/README.md +0 -0
  12. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/pyproject.toml +0 -0
  13. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/pytrilogy.egg-info/dependency_links.txt +0 -0
  14. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/pytrilogy.egg-info/entry_points.txt +0 -0
  15. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/pytrilogy.egg-info/requires.txt +0 -0
  16. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/pytrilogy.egg-info/top_level.txt +0 -0
  17. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/setup.cfg +0 -0
  18. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/setup.py +0 -0
  19. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_datatypes.py +0 -0
  20. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_declarations.py +0 -0
  21. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_derived_concepts.py +0 -0
  22. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_discovery_nodes.py +0 -0
  23. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_enums.py +0 -0
  24. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_environment.py +0 -0
  25. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_executor.py +0 -0
  26. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_failure.py +0 -0
  27. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_functions.py +0 -0
  28. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_imports.py +0 -0
  29. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_metadata.py +0 -0
  30. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_models.py +0 -0
  31. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_multi_join_assignments.py +0 -0
  32. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_parse_engine.py +0 -0
  33. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_partial_handling.py +0 -0
  34. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_query_processing.py +0 -0
  35. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_query_render.py +0 -0
  36. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_select.py +0 -0
  37. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_show.py +0 -0
  38. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_statements.py +0 -0
  39. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_typing.py +0 -0
  40. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_undefined_concept.py +0 -0
  41. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_user_functions.py +0 -0
  42. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/tests/test_where_clause.py +0 -0
  43. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/authoring/__init__.py +0 -0
  44. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/compiler.py +0 -0
  45. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/constants.py +0 -0
  46. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/__init__.py +0 -0
  47. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/constants.py +0 -0
  48. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/enums.py +0 -0
  49. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/env_processor.py +0 -0
  50. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/environment_helpers.py +0 -0
  51. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/ergonomics.py +0 -0
  52. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/exceptions.py +0 -0
  53. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/functions.py +0 -0
  54. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/graph_models.py +0 -0
  55. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/internal.py +0 -0
  56. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/models/__init__.py +0 -0
  57. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/models/author.py +0 -0
  58. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/models/build.py +0 -0
  59. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/models/build_environment.py +0 -0
  60. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/models/core.py +0 -0
  61. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/models/datasource.py +0 -0
  62. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/models/environment.py +0 -0
  63. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/models/execute.py +0 -0
  64. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/optimization.py +0 -0
  65. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/optimizations/__init__.py +0 -0
  66. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/optimizations/base_optimization.py +0 -0
  67. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/optimizations/inline_constant.py +0 -0
  68. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/optimizations/inline_datasource.py +0 -0
  69. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  70. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/__init__.py +0 -0
  71. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/concept_strategies_v3.py +0 -0
  72. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/graph_utils.py +0 -0
  73. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/__init__.py +0 -0
  74. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  75. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/common.py +0 -0
  76. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  77. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/group_node.py +0 -0
  78. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  79. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  80. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  81. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  82. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
  83. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
  84. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
  85. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/select_node.py +0 -0
  86. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
  87. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/union_node.py +0 -0
  88. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  89. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/nodes/__init__.py +0 -0
  90. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/nodes/base_node.py +0 -0
  91. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/nodes/filter_node.py +0 -0
  92. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/nodes/group_node.py +0 -0
  93. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/nodes/merge_node.py +0 -0
  94. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  95. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/nodes/union_node.py +0 -0
  96. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  97. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/nodes/window_node.py +0 -0
  98. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/processing/utility.py +0 -0
  99. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/query_processor.py +0 -0
  100. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/statements/__init__.py +0 -0
  101. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/statements/author.py +0 -0
  102. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/statements/build.py +0 -0
  103. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/statements/common.py +0 -0
  104. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/core/statements/execute.py +0 -0
  105. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/__init__.py +0 -0
  106. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/base.py +0 -0
  107. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/common.py +0 -0
  108. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/config.py +0 -0
  109. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/dataframe.py +0 -0
  110. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/duckdb.py +0 -0
  111. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/enums.py +0 -0
  112. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/postgres.py +0 -0
  113. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/presto.py +0 -0
  114. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/snowflake.py +0 -0
  115. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/dialect/sql_server.py +0 -0
  116. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/engine.py +0 -0
  117. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/executor.py +0 -0
  118. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/hooks/__init__.py +0 -0
  119. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/hooks/base_hook.py +0 -0
  120. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/hooks/graph_hook.py +0 -0
  121. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/hooks/query_debugger.py +0 -0
  122. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/metadata/__init__.py +0 -0
  123. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/parser.py +0 -0
  124. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/parsing/__init__.py +0 -0
  125. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/parsing/common.py +0 -0
  126. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/parsing/config.py +0 -0
  127. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/parsing/exceptions.py +0 -0
  128. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/parsing/helpers.py +0 -0
  129. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/parsing/render.py +0 -0
  130. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/parsing/trilogy.lark +0 -0
  131. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/py.typed +0 -0
  132. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/render.py +0 -0
  133. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/scripts/__init__.py +0 -0
  134. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/scripts/trilogy.py +0 -0
  135. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/std/__init__.py +0 -0
  136. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/std/date.preql +0 -0
  137. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/std/display.preql +0 -0
  138. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/std/geography.preql +0 -0
  139. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/std/money.preql +0 -0
  140. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/std/report.preql +0 -0
  141. {pytrilogy-0.0.3.42 → pytrilogy-0.0.3.43}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytrilogy
3
- Version: 0.0.3.42
3
+ Version: 0.0.3.43
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.42
3
+ Version: 0.0.3.43
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -23,6 +23,7 @@ tests/test_models.py
23
23
  tests/test_multi_join_assignments.py
24
24
  tests/test_parse_engine.py
25
25
  tests/test_parsing.py
26
+ tests/test_parsing_failures.py
26
27
  tests/test_partial_handling.py
27
28
  tests/test_query_processing.py
28
29
  tests/test_query_render.py
@@ -1,9 +1,6 @@
1
- from pytest import raises
2
-
3
1
  from trilogy import Dialects
4
- from trilogy.constants import MagicConstants, Parsing
2
+ from trilogy.constants import MagicConstants
5
3
  from trilogy.core.enums import BooleanOperator, ComparisonOperator, Purpose
6
- from trilogy.core.exceptions import InvalidSyntaxException
7
4
  from trilogy.core.functions import argument_to_purpose, function_args_to_output_purpose
8
5
  from trilogy.core.models.author import Comparison
9
6
  from trilogy.core.models.core import (
@@ -20,7 +17,6 @@ from trilogy.core.statements.author import SelectStatement, ShowStatement
20
17
  from trilogy.core.statements.execute import ProcessedQuery
21
18
  from trilogy.dialect.base import BaseDialect
22
19
  from trilogy.parsing.parse_engine import (
23
- ParseError,
24
20
  arg_to_datatype,
25
21
  parse_text,
26
22
  )
@@ -668,99 +664,3 @@ select x % 10 -> x_mod_10;
668
664
 
669
665
  """
670
666
  )
671
-
672
-
673
- def test_import_shows_source():
674
-
675
- env = Environment(
676
- config=EnvironmentOptions(
677
- import_resolver=DictImportResolver(
678
- content={
679
- "test": """
680
- import test_dep as test_dep;
681
- key x int;
682
- datasource test (
683
- x: x)
684
- grain(x)
685
- query '''
686
- select 1 as x
687
- union all
688
- select 11 as x
689
- ''' TYPO
690
- """,
691
- "test_dep": """
692
- key x int;
693
- """,
694
- }
695
- )
696
- )
697
- )
698
- assert isinstance(env.config.import_resolver, DictImportResolver)
699
-
700
- with raises(Exception, match="Unable to import 'test', parsing error") as e:
701
- env.parse(
702
- """
703
- import test;
704
-
705
- select x % 10 -> x_mod_10;
706
-
707
-
708
- """
709
- )
710
- assert "TYPO" in str(e.value)
711
- assert 1 == 0
712
-
713
-
714
- def test_concept_shadow_warning():
715
- x = """
716
- key scalar int;
717
- property scalar.int_array list<int>;
718
-
719
- key split <- unnest(int_array);
720
-
721
- datasource avalues (
722
- int_array: int_array,
723
- scalar: scalar
724
- )
725
- grain (scalar)
726
- query '''(
727
- select [1,2,3,4] as int_array, 2 as scalar
728
- union all
729
- select [5,6,7,8] as int_array, 4 as scalar
730
- )''';
731
-
732
- SELECT
733
- int_array,
734
- 1+2->scalar
735
- ;
736
- """
737
- with raises(ParseError):
738
- env, parsed = parse_text(
739
- x, parse_config=Parsing(strict_name_shadow_enforcement=True)
740
- )
741
- x = """
742
- key scalar int;
743
- property scalar.int_array list<int>;
744
-
745
- key split <- unnest(int_array);
746
-
747
- datasource avalues (
748
- int_array: int_array,
749
- scalar: scalar
750
- )
751
- grain (scalar)
752
- query '''(
753
- select [1,2,3,4] as int_array, 2 as scalar
754
- union all
755
- select [5,6,7,8] as int_array, 4 as scalar
756
- )''';
757
-
758
- SELECT
759
- int_array,
760
- sum(scalar)->scalar
761
- ;
762
- """
763
- with raises(InvalidSyntaxException):
764
- env, parsed = parse_text(
765
- x, parse_config=Parsing(strict_name_shadow_enforcement=True)
766
- )
@@ -0,0 +1,142 @@
1
+ from pytest import raises
2
+
3
+ from trilogy.constants import Parsing
4
+ from trilogy.core.exceptions import InvalidSyntaxException
5
+ from trilogy.core.models.environment import (
6
+ DictImportResolver,
7
+ Environment,
8
+ EnvironmentOptions,
9
+ )
10
+ from trilogy.parsing.parse_engine import (
11
+ ParseError,
12
+ parse_text,
13
+ )
14
+
15
+
16
+ def test_import_shows_source():
17
+
18
+ env = Environment(
19
+ config=EnvironmentOptions(
20
+ import_resolver=DictImportResolver(
21
+ content={
22
+ "test": """
23
+ import test_dep as test_dep;
24
+ key x int;
25
+ datasource test (
26
+ x: x)
27
+ grain(x)
28
+ query '''
29
+ select 1 as x
30
+ union all
31
+ select 11 as x
32
+ ''' TYPO
33
+ """,
34
+ "test_dep": """
35
+ key x int;
36
+ """,
37
+ }
38
+ )
39
+ )
40
+ )
41
+ assert isinstance(env.config.import_resolver, DictImportResolver)
42
+
43
+ with raises(Exception, match="Unable to import 'test', parsing error") as e:
44
+ env.parse(
45
+ """
46
+ import test;
47
+
48
+ select x % 10 -> x_mod_10;
49
+
50
+
51
+ """
52
+ )
53
+ assert "TYPO" in str(e.value)
54
+ assert 1 == 0
55
+
56
+
57
+ def test_concept_shadow_warning():
58
+ x = """
59
+ key scalar int;
60
+ property scalar.int_array list<int>;
61
+
62
+ key split <- unnest(int_array);
63
+
64
+ datasource avalues (
65
+ int_array: int_array,
66
+ scalar: scalar
67
+ )
68
+ grain (scalar)
69
+ query '''(
70
+ select [1,2,3,4] as int_array, 2 as scalar
71
+ union all
72
+ select [5,6,7,8] as int_array, 4 as scalar
73
+ )''';
74
+
75
+ SELECT
76
+ int_array,
77
+ 1+2->scalar
78
+ ;
79
+ """
80
+ with raises(ParseError):
81
+ env, parsed = parse_text(
82
+ x, parse_config=Parsing(strict_name_shadow_enforcement=True)
83
+ )
84
+ x = """
85
+ key scalar int;
86
+ property scalar.int_array list<int>;
87
+
88
+ key split <- unnest(int_array);
89
+
90
+ datasource avalues (
91
+ int_array: int_array,
92
+ scalar: scalar
93
+ )
94
+ grain (scalar)
95
+ query '''(
96
+ select [1,2,3,4] as int_array, 2 as scalar
97
+ union all
98
+ select [5,6,7,8] as int_array, 4 as scalar
99
+ )''';
100
+
101
+ SELECT
102
+ int_array,
103
+ sum(scalar)->scalar
104
+ ;
105
+ """
106
+ with raises(InvalidSyntaxException):
107
+ env, parsed = parse_text(
108
+ x, parse_config=Parsing(strict_name_shadow_enforcement=True)
109
+ )
110
+
111
+
112
+ def test_parsing_bad_order():
113
+ x = """
114
+ key scalar int;
115
+ property scalar.int_array list<int>;
116
+
117
+ key split <- unnest(int_array);
118
+
119
+ datasource avalues (
120
+ int_array: int_array,
121
+ scalar: scalar
122
+ )
123
+ grain (scalar)
124
+ query '''(
125
+ select [1,2,3,4] as int_array, 2 as scalar
126
+ union all
127
+ select [5,6,7,8] as int_array, 4 as scalar
128
+ )''';
129
+
130
+ SELECT
131
+ int_array,
132
+ sum(scalar)->scalar
133
+ order
134
+ int_array asc
135
+ ;
136
+ """
137
+ with raises(InvalidSyntaxException) as e:
138
+
139
+ env, parsed = parse_text(
140
+ x, parse_config=Parsing(strict_name_shadow_enforcement=True)
141
+ )
142
+ assert "^" in str(e)
@@ -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.42"
7
+ __version__ = "0.0.3.43"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -61,6 +61,9 @@ def gen_window_node(
61
61
  # append in keys to get the right grain
62
62
  if concept.keys:
63
63
  for item in concept.keys:
64
+ logger.info(
65
+ f"{padding(depth)}{LOGGER_PREFIX} appending search for key {item}"
66
+ )
64
67
  targets.append(environment.concepts[item])
65
68
  additional_outputs = []
66
69
  if equivalent_optional:
@@ -72,10 +75,15 @@ def gen_window_node(
72
75
  additional_outputs.append(x)
73
76
 
74
77
  grain_equivalents = [
75
- x for x in local_optional if x.keys and all([key in targets for key in x.keys])
78
+ x
79
+ for x in local_optional
80
+ if x.keys
81
+ and all([key in targets for key in x.keys])
82
+ and x.grain == concept.grain
76
83
  ]
77
84
 
78
85
  for x in grain_equivalents:
86
+ logger.info("Appending grain equivalent %s", x)
79
87
  targets.append(x)
80
88
 
81
89
  # finally, the ones we'll need to enrich
@@ -34,7 +34,7 @@ FUNCTION_MAP = {
34
34
 
35
35
  FUNCTION_GRAIN_MATCH_MAP = {
36
36
  **FUNCTION_MAP,
37
- FunctionType.COUNT: lambda args: f"{args[0]}",
37
+ FunctionType.COUNT: lambda args: "1",
38
38
  FunctionType.SUM: lambda args: f"{args[0]}",
39
39
  FunctionType.AVG: lambda args: f"{args[0]}",
40
40
  }
@@ -1464,7 +1464,7 @@ class ParseToObjects(Transformer):
1464
1464
  return DatePart(args.value)
1465
1465
 
1466
1466
  @v_args(meta=True)
1467
- def window_item(self, meta, args) -> WindowItem:
1467
+ def window_item(self, meta: Meta, args) -> WindowItem:
1468
1468
  type: WindowType = args[0]
1469
1469
  order_by = []
1470
1470
  over = []
@@ -1486,7 +1486,10 @@ class ParseToObjects(Transformer):
1486
1486
  else:
1487
1487
  concept = arbitrary_to_concept(item, environment=self.environment)
1488
1488
  self.environment.add_concept(concept, meta=meta)
1489
- assert concept
1489
+ if not concept:
1490
+ raise ParseError(
1491
+ f"Window statements must be on fields, not constants - error in: `{self.text_lookup[self.parse_address][meta.start_pos:meta.end_pos]}`"
1492
+ )
1490
1493
  return WindowItem(
1491
1494
  type=type,
1492
1495
  content=concept.reference,
@@ -1815,16 +1818,24 @@ class ParseToObjects(Transformer):
1815
1818
  return self.function_factory.create_function(args, FunctionType.BOOL, meta)
1816
1819
 
1817
1820
 
1818
- def unpack_visit_error(e: VisitError):
1821
+ def unpack_visit_error(e: VisitError, text: str | None = None):
1819
1822
  """This is required to get exceptions from imports, which would
1820
1823
  raise nested VisitErrors"""
1821
1824
  if isinstance(e.orig_exc, VisitError):
1822
- unpack_visit_error(e.orig_exc)
1825
+ unpack_visit_error(e.orig_exc, text)
1823
1826
  elif isinstance(e.orig_exc, (UndefinedConceptException, ImportError)):
1824
1827
  raise e.orig_exc
1825
1828
  elif isinstance(e.orig_exc, (SyntaxError, TypeError)):
1826
1829
  if isinstance(e.obj, Tree):
1827
- raise InvalidSyntaxException(
1830
+ if text:
1831
+ extract = text[e.obj.meta.start_pos - 5 : e.obj.meta.end_pos + 5]
1832
+ raise InvalidSyntaxException(
1833
+ str(e.orig_exc)
1834
+ + " in "
1835
+ + str(e.rule)
1836
+ + f" Line: {e.obj.meta.line} ({extract})"
1837
+ )
1838
+ InvalidSyntaxException(
1828
1839
  str(e.orig_exc) + " in " + str(e.rule) + f" Line: {e.obj.meta.line}"
1829
1840
  )
1830
1841
  raise InvalidSyntaxException(str(e.orig_exc)).with_traceback(
@@ -1875,7 +1886,7 @@ def parse_text(
1875
1886
  f"Parse time: {end - start} for {len(text)} characters, {len(output)} objects"
1876
1887
  )
1877
1888
  except VisitError as e:
1878
- unpack_visit_error(e)
1889
+ unpack_visit_error(e, text)
1879
1890
  # this will never be reached
1880
1891
  raise e
1881
1892
  except (
@@ -1886,6 +1897,12 @@ def parse_text(
1886
1897
  ValidationError,
1887
1898
  TypeError,
1888
1899
  ) as e:
1900
+ if isinstance(
1901
+ e, (UnexpectedCharacters, UnexpectedEOF, UnexpectedInput, UnexpectedToken)
1902
+ ):
1903
+ raise InvalidSyntaxException(
1904
+ str(e) + "\nContext:\n" + e.get_context(text.replace("\n", " "), 20)
1905
+ )
1889
1906
  raise InvalidSyntaxException(str(e))
1890
1907
 
1891
1908
  return environment, output
File without changes
File without changes
File without changes
File without changes