pytrilogy 0.0.3.76__tar.gz → 0.0.3.77__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 (150) hide show
  1. {pytrilogy-0.0.3.76/pytrilogy.egg-info → pytrilogy-0.0.3.77}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_parse_engine.py +34 -6
  4. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/__init__.py +1 -1
  5. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/parsing/parse_engine.py +47 -4
  6. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/parsing/trilogy.lark +3 -1
  7. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/LICENSE.md +0 -0
  8. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/README.md +0 -0
  9. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/pyproject.toml +0 -0
  10. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/pytrilogy.egg-info/SOURCES.txt +0 -0
  11. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/pytrilogy.egg-info/dependency_links.txt +0 -0
  12. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/pytrilogy.egg-info/entry_points.txt +0 -0
  13. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/pytrilogy.egg-info/requires.txt +0 -0
  14. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/pytrilogy.egg-info/top_level.txt +0 -0
  15. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/setup.cfg +0 -0
  16. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/setup.py +0 -0
  17. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_datatypes.py +0 -0
  18. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_declarations.py +0 -0
  19. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_derived_concepts.py +0 -0
  20. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_discovery_nodes.py +0 -0
  21. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_enums.py +0 -0
  22. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_environment.py +0 -0
  23. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_execute_models.py +0 -0
  24. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_executor.py +0 -0
  25. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_failure.py +0 -0
  26. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_functions.py +0 -0
  27. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_imports.py +0 -0
  28. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_metadata.py +0 -0
  29. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_models.py +0 -0
  30. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_multi_join_assignments.py +0 -0
  31. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_parsing.py +0 -0
  32. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_parsing_failures.py +0 -0
  33. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_partial_handling.py +0 -0
  34. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_query_processing.py +0 -0
  35. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_query_render.py +0 -0
  36. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_select.py +0 -0
  37. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_show.py +0 -0
  38. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_statements.py +0 -0
  39. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_typing.py +0 -0
  40. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_undefined_concept.py +0 -0
  41. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_user_functions.py +0 -0
  42. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/tests/test_where_clause.py +0 -0
  43. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/authoring/__init__.py +0 -0
  44. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/compiler.py +0 -0
  45. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/constants.py +0 -0
  46. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/__init__.py +0 -0
  47. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/constants.py +0 -0
  48. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/enums.py +0 -0
  49. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/env_processor.py +0 -0
  50. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/environment_helpers.py +0 -0
  51. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/ergonomics.py +0 -0
  52. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/exceptions.py +0 -0
  53. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/functions.py +0 -0
  54. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/graph_models.py +0 -0
  55. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/internal.py +0 -0
  56. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/models/__init__.py +0 -0
  57. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/models/author.py +0 -0
  58. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/models/build.py +0 -0
  59. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/models/build_environment.py +0 -0
  60. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/models/core.py +0 -0
  61. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/models/datasource.py +0 -0
  62. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/models/environment.py +0 -0
  63. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/models/execute.py +0 -0
  64. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/optimization.py +0 -0
  65. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/optimizations/__init__.py +0 -0
  66. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/optimizations/base_optimization.py +0 -0
  67. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/optimizations/inline_datasource.py +0 -0
  68. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  69. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/__init__.py +0 -0
  70. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/concept_strategies_v3.py +0 -0
  71. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/discovery_loop.py +0 -0
  72. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/discovery_node_factory.py +0 -0
  73. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/discovery_utility.py +0 -0
  74. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/discovery_validation.py +0 -0
  75. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/graph_utils.py +0 -0
  76. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/__init__.py +0 -0
  77. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  78. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/common.py +0 -0
  79. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  80. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/group_node.py +0 -0
  81. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  82. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  83. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  84. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/recursive_node.py +0 -0
  85. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  86. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
  87. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
  88. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
  89. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/select_node.py +0 -0
  90. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
  91. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/union_node.py +0 -0
  92. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  93. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/node_generators/window_node.py +0 -0
  94. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/nodes/__init__.py +0 -0
  95. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/nodes/base_node.py +0 -0
  96. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/nodes/filter_node.py +0 -0
  97. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/nodes/group_node.py +0 -0
  98. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/nodes/merge_node.py +0 -0
  99. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/nodes/recursive_node.py +0 -0
  100. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  101. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/nodes/union_node.py +0 -0
  102. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  103. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/nodes/window_node.py +0 -0
  104. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/processing/utility.py +0 -0
  105. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/query_processor.py +0 -0
  106. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/statements/__init__.py +0 -0
  107. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/statements/author.py +0 -0
  108. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/statements/build.py +0 -0
  109. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/statements/common.py +0 -0
  110. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/statements/execute.py +0 -0
  111. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/core/utility.py +0 -0
  112. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/__init__.py +0 -0
  113. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/base.py +0 -0
  114. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/bigquery.py +0 -0
  115. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/common.py +0 -0
  116. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/config.py +0 -0
  117. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/dataframe.py +0 -0
  118. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/duckdb.py +0 -0
  119. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/enums.py +0 -0
  120. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/postgres.py +0 -0
  121. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/presto.py +0 -0
  122. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/snowflake.py +0 -0
  123. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/dialect/sql_server.py +0 -0
  124. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/engine.py +0 -0
  125. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/executor.py +0 -0
  126. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/hooks/__init__.py +0 -0
  127. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/hooks/base_hook.py +0 -0
  128. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/hooks/graph_hook.py +0 -0
  129. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/hooks/query_debugger.py +0 -0
  130. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/metadata/__init__.py +0 -0
  131. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/parser.py +0 -0
  132. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/parsing/__init__.py +0 -0
  133. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/parsing/common.py +0 -0
  134. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/parsing/config.py +0 -0
  135. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/parsing/exceptions.py +0 -0
  136. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/parsing/helpers.py +0 -0
  137. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/parsing/render.py +0 -0
  138. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/py.typed +0 -0
  139. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/render.py +0 -0
  140. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/scripts/__init__.py +0 -0
  141. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/scripts/trilogy.py +0 -0
  142. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/std/__init__.py +0 -0
  143. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/std/date.preql +0 -0
  144. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/std/display.preql +0 -0
  145. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/std/geography.preql +0 -0
  146. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/std/money.preql +0 -0
  147. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/std/net.preql +0 -0
  148. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/std/ranking.preql +0 -0
  149. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/std/report.preql +0 -0
  150. {pytrilogy-0.0.3.76 → pytrilogy-0.0.3.77}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytrilogy
3
- Version: 0.0.3.76
3
+ Version: 0.0.3.77
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.76
3
+ Version: 0.0.3.77
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -3,6 +3,7 @@ from pytest import raises
3
3
  from trilogy.core.exceptions import UndefinedConceptException
4
4
  from trilogy.core.models.environment import Environment
5
5
  from trilogy.parsing.parse_engine import (
6
+ ERROR_CODES,
6
7
  PARSER,
7
8
  InvalidSyntaxException,
8
9
  ParseToObjects,
@@ -66,18 +67,45 @@ address fun;
66
67
  x.run_second_parse_pass()
67
68
 
68
69
 
69
- TEXT2 = """
70
+ def test_from_error():
71
+ env = Environment()
72
+ TEXT2 = """
73
+ const a <- 1;
74
+
75
+ select
76
+ a,
77
+ FROM a
78
+ ;
79
+ """
80
+ with raises(InvalidSyntaxException) as e:
81
+ env.parse(TEXT2)
82
+ assert ERROR_CODES[101] in str(e.value), e.value
83
+
84
+
85
+ def test_error_order_by_missing():
86
+ env = Environment()
87
+ TEXT2 = """
70
88
  const a <- 1;
71
89
 
72
90
  select
73
91
  a,
74
- FROM a
92
+ order by a
75
93
  ;
76
- """
94
+ """
95
+ with raises(InvalidSyntaxException) as e:
96
+ env.parse(TEXT2)
97
+ assert ERROR_CODES[210] in str(e.value)
77
98
 
78
99
 
79
- def test_from_error():
100
+ def test_alias_error():
80
101
  env = Environment()
81
-
82
- with raises(InvalidSyntaxException):
102
+ TEXT2 = """
103
+ const a <- 1;
104
+
105
+ select
106
+ a+2 fun,
107
+ ;
108
+ """
109
+ with raises(InvalidSyntaxException) as e:
83
110
  env.parse(TEXT2)
111
+ assert ERROR_CODES[201] in str(e.value), e.value
@@ -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.76"
7
+ __version__ = "0.0.3.77"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -7,7 +7,7 @@ from pathlib import Path
7
7
  from re import IGNORECASE
8
8
  from typing import Any, List, Optional, Tuple, Union
9
9
 
10
- from lark import Lark, ParseTree, Transformer, Tree, v_args
10
+ from lark import Lark, ParseTree, Token, Transformer, Tree, v_args
11
11
  from lark.exceptions import (
12
12
  UnexpectedCharacters,
13
13
  UnexpectedEOF,
@@ -2091,6 +2091,15 @@ def parse_text_raw(text: str, environment: Optional[Environment] = None):
2091
2091
  PARSER.parse(text)
2092
2092
 
2093
2093
 
2094
+ ERROR_CODES: dict[int, str] = {
2095
+ # 100 code are SQL compatability errors
2096
+ 101: "Trilogy does not have a FROM clause (Datasource resolution is automatic). Remove the FROM clause.",
2097
+ # 200 codes relate to required explicit syntax (we could loosen these?)
2098
+ 201: 'Alias must be specified with "AS" - e.g. `SELECT x AS y`',
2099
+ 210: "Order by must be explicit about direction - specify `asc` or `desc`.",
2100
+ }
2101
+
2102
+
2094
2103
  def parse_text(
2095
2104
  text: str,
2096
2105
  environment: Optional[Environment] = None,
@@ -2140,9 +2149,43 @@ def parse_text(
2140
2149
  ValidationError,
2141
2150
  TypeError,
2142
2151
  ) as e:
2143
- if isinstance(
2144
- e, (UnexpectedCharacters, UnexpectedEOF, UnexpectedInput, UnexpectedToken)
2145
- ):
2152
+ if isinstance(e, UnexpectedToken):
2153
+ if e.expected == {"ORDERING_DIRECTION"}:
2154
+ code = 210
2155
+ raise InvalidSyntaxException(
2156
+ f"Syntax [{code}]:"
2157
+ + ERROR_CODES[code]
2158
+ + "\nContext:\n"
2159
+ + e.get_context(text.replace("\n", " "), 20)
2160
+ )
2161
+ parsed_tokens = (
2162
+ [x.value for x in e.token_history] if e.token_history else []
2163
+ )
2164
+ if parsed_tokens == ["FROM"]:
2165
+ code = 101
2166
+ raise InvalidSyntaxException(
2167
+ f"Syntax [{code}]:"
2168
+ + ERROR_CODES[code]
2169
+ + "\nContext:\n"
2170
+ + e.get_context(text.replace("\n", " "), 20)
2171
+ )
2172
+ # recovery attempt for aliasing
2173
+ try:
2174
+ e.interactive_parser.feed_token(Token("AS", "AS"))
2175
+ e.interactive_parser.feed_token(e.token)
2176
+ raise InvalidSyntaxException(
2177
+ f"Syntax [{ERROR_CODES[201]}]:"
2178
+ + ERROR_CODES[201]
2179
+ + "\nContext:\n"
2180
+ + e.get_context(text.replace("\n", " "), 20)
2181
+ )
2182
+ except UnexpectedToken:
2183
+ pass
2184
+ raise InvalidSyntaxException(
2185
+ str(e) + "\nContext:\n" + e.get_context(text.replace("\n", " "), 20)
2186
+ )
2187
+ elif isinstance(e, (UnexpectedCharacters, UnexpectedEOF, UnexpectedInput)):
2188
+
2146
2189
  raise InvalidSyntaxException(
2147
2190
  str(e) + "\nContext:\n" + e.get_context(text.replace("\n", " "), 20)
2148
2191
  )
@@ -130,7 +130,9 @@
130
130
 
131
131
  over_list: concept_lit ("," concept_lit )* ","?
132
132
 
133
- !ordering: /ASC|DESC/i ("NULLS"i /FIRST|LAST|AUTO/i )?
133
+ ORDERING_DIRECTION: /ASC|DESC/i
134
+
135
+ !ordering: ORDERING_DIRECTION ("NULLS"i /FIRST|LAST|AUTO/i )?
134
136
 
135
137
  order_by: "ORDER"i "BY"i order_list
136
138
 
File without changes
File without changes
File without changes
File without changes