From 43116263ddd002b99ddabb3a4cee6b598c90a794 Mon Sep 17 00:00:00 2001 From: Peng Ren Date: Mon, 29 Dec 2025 14:18:23 -0500 Subject: [PATCH 1/5] Refactor core functions for sql parser --- pymongosql/__init__.py | 2 +- pymongosql/sql/ast.py | 112 +++++++++----------------------------- pymongosql/sql/builder.py | 111 ++++++++++++++++++++++++++++++++++++- pymongosql/sql/handler.py | 79 ++++++--------------------- pymongosql/sql/parser.py | 7 ++- 5 files changed, 159 insertions(+), 152 deletions(-) diff --git a/pymongosql/__init__.py b/pymongosql/__init__.py index fae40bd..ae4b077 100644 --- a/pymongosql/__init__.py +++ b/pymongosql/__init__.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from .connection import Connection -__version__: str = "0.3.0" +__version__: str = "0.3.1" # Globals https://www.python.org/dev/peps/pep-0249/#globals apilevel: str = "2.0" diff --git a/pymongosql/sql/ast.py b/pymongosql/sql/ast.py index f9f3ed8..e95e458 100644 --- a/pymongosql/sql/ast.py +++ b/pymongosql/sql/ast.py @@ -3,18 +3,13 @@ from typing import Any, Dict, Union from ..error import SqlSyntaxError -from .builder import BuilderFactory -from .delete_builder import DeleteExecutionPlan from .delete_handler import DeleteParseResult from .handler import BaseHandler, HandlerFactory -from .insert_builder import InsertExecutionPlan from .insert_handler import InsertParseResult from .partiql.PartiQLLexer import PartiQLLexer from .partiql.PartiQLParser import PartiQLParser from .partiql.PartiQLParserVisitor import PartiQLParserVisitor -from .query_builder import QueryExecutionPlan from .query_handler import QueryParseResult -from .update_builder import UpdateExecutionPlan from .update_handler import UpdateParseResult _logger = logging.getLogger(__name__) @@ -37,7 +32,7 @@ class MongoSQLParserVisitor(PartiQLParserVisitor): def __init__(self) -> None: super().__init__() - self._parse_result = QueryParseResult.for_visitor() + self._query_parse_result = QueryParseResult.for_visitor() self._insert_parse_result = InsertParseResult.for_visitor() self._delete_parse_result = DeleteParseResult.for_visitor() self._update_parse_result = UpdateParseResult.for_visitor() @@ -58,86 +53,27 @@ def _initialize_handlers(self) -> Dict[str, BaseHandler]: } @property - def parse_result(self) -> QueryParseResult: - """Get the current parse result""" - return self._parse_result - - def parse_to_execution_plan( - self, - ) -> Union[QueryExecutionPlan, InsertExecutionPlan, DeleteExecutionPlan, UpdateExecutionPlan]: - """Convert the parse result to an execution plan using BuilderFactory.""" + def parse_result(self) -> Union[QueryParseResult, InsertParseResult, DeleteParseResult, UpdateParseResult]: + """Get the current parse result based on the current operation""" if self._current_operation == "insert": - return self._build_insert_plan() + return self._insert_parse_result elif self._current_operation == "delete": - return self._build_delete_plan() + return self._delete_parse_result elif self._current_operation == "update": - return self._build_update_plan() + return self._update_parse_result + else: + return self._query_parse_result - return self._build_query_plan() - - def _build_query_plan(self) -> QueryExecutionPlan: - """Build a query execution plan from SELECT parsing.""" - builder = BuilderFactory.create_query_builder().collection(self._parse_result.collection) - - builder.filter(self._parse_result.filter_conditions).project(self._parse_result.projection).column_aliases( - self._parse_result.column_aliases - ).sort(self._parse_result.sort_fields).limit(self._parse_result.limit_value).skip( - self._parse_result.offset_value - ) - - return builder.build() - - def _build_insert_plan(self) -> InsertExecutionPlan: - """Build an INSERT execution plan from INSERT parsing.""" - if self._insert_parse_result.has_errors: - raise SqlSyntaxError(self._insert_parse_result.error_message or "INSERT parsing failed") - - builder = BuilderFactory.create_insert_builder().collection(self._insert_parse_result.collection) - - documents = self._insert_parse_result.insert_documents or [] - builder.insert_documents(documents) - - if self._insert_parse_result.parameter_style: - builder.parameter_style(self._insert_parse_result.parameter_style) - - if self._insert_parse_result.parameter_count > 0: - builder.parameter_count(self._insert_parse_result.parameter_count) - - return builder.build() - - def _build_delete_plan(self) -> DeleteExecutionPlan: - """Build a DELETE execution plan from DELETE parsing.""" - _logger.debug( - f"Building DELETE plan with collection: {self._delete_parse_result.collection}, " - f"filters: {self._delete_parse_result.filter_conditions}" - ) - builder = BuilderFactory.create_delete_builder().collection(self._delete_parse_result.collection) - - if self._delete_parse_result.filter_conditions: - builder.filter_conditions(self._delete_parse_result.filter_conditions) - - return builder.build() - - def _build_update_plan(self) -> UpdateExecutionPlan: - """Build an UPDATE execution plan from UPDATE parsing.""" - _logger.debug( - f"Building UPDATE plan with collection: {self._update_parse_result.collection}, " - f"update_fields: {self._update_parse_result.update_fields}, " - f"filters: {self._update_parse_result.filter_conditions}" - ) - builder = BuilderFactory.create_update_builder().collection(self._update_parse_result.collection) - - if self._update_parse_result.update_fields: - builder.update_fields(self._update_parse_result.update_fields) - - if self._update_parse_result.filter_conditions: - builder.filter_conditions(self._update_parse_result.filter_conditions) - - return builder.build() + @property + def current_operation(self) -> str: + """Get the current operation type (select, insert, delete, or update)""" + return self._current_operation def visitRoot(self, ctx: PartiQLParser.RootContext) -> Any: """Visit root node and process child nodes""" _logger.debug("Starting to parse SQL query") + # Reset to default SELECT operation at the start of each query + self._current_operation = "select" try: result = self.visitChildren(ctx) return result @@ -149,7 +85,7 @@ def visitSelectAll(self, ctx: PartiQLParser.SelectAllContext) -> Any: """Handle SELECT * statements""" _logger.debug("Processing SELECT ALL statement") # SELECT * means no projection filter (return all fields) - self._parse_result.projection = {} + self._query_parse_result.projection = {} return self.visitChildren(ctx) def visitSelectItems(self, ctx: PartiQLParser.SelectItemsContext) -> Any: @@ -158,7 +94,7 @@ def visitSelectItems(self, ctx: PartiQLParser.SelectItemsContext) -> Any: try: handler = self._handlers["select"] if handler: - result = handler.handle_visitor(ctx, self._parse_result) + result = handler.handle_visitor(ctx, self._query_parse_result) return result return self.visitChildren(ctx) except Exception as e: @@ -171,7 +107,7 @@ def visitFromClause(self, ctx: PartiQLParser.FromClauseContext) -> Any: try: handler = self._handlers["from"] if handler: - result = handler.handle_visitor(ctx, self._parse_result) + result = handler.handle_visitor(ctx, self._query_parse_result) _logger.debug(f"Extracted collection: {result}") return result return self.visitChildren(ctx) @@ -185,7 +121,7 @@ def visitWhereClauseSelect(self, ctx: PartiQLParser.WhereClauseSelectContext) -> try: handler = self._handlers["where"] if handler: - result = handler.handle_visitor(ctx, self._parse_result) + result = handler.handle_visitor(ctx, self._query_parse_result) _logger.debug(f"Extracted filter conditions: {result}") return result return self.visitChildren(ctx) @@ -197,6 +133,8 @@ def visitInsertStatement(self, ctx: PartiQLParser.InsertStatementContext) -> Any """Handle INSERT statements via the insert handler.""" _logger.debug("Processing INSERT statement") self._current_operation = "insert" + # Reset insert parse result for this statement + self._insert_parse_result = InsertParseResult.for_visitor() handler = self._handlers.get("insert") if handler: return handler.handle_visitor(ctx, self._insert_parse_result) @@ -206,6 +144,8 @@ def visitInsertStatementLegacy(self, ctx: PartiQLParser.InsertStatementLegacyCon """Handle legacy INSERT statements.""" _logger.debug("Processing INSERT legacy statement") self._current_operation = "insert" + # Reset insert parse result for this statement + self._insert_parse_result = InsertParseResult.for_visitor() handler = self._handlers.get("insert") if handler: return handler.handle_visitor(ctx, self._insert_parse_result) @@ -247,7 +187,7 @@ def visitWhereClause(self, ctx: PartiQLParser.WhereClauseContext) -> Any: # For other operations, use the where handler handler = self._handlers["where"] if handler: - result = handler.handle_visitor(ctx, self._parse_result) + result = handler.handle_visitor(ctx, self._query_parse_result) _logger.debug(f"Extracted filter conditions: {result}") return result return {} @@ -284,7 +224,7 @@ def visitOrderByClause(self, ctx: PartiQLParser.OrderByClauseContext) -> Any: # Convert to the expected format: List[Dict[str, int]] sort_specs.append({field_name: direction}) - self._parse_result.sort_fields = sort_specs + self._query_parse_result.sort_fields = sort_specs _logger.debug(f"Extracted sort specifications: {sort_specs}") return self.visitChildren(ctx) except Exception as e: @@ -299,7 +239,7 @@ def visitLimitClause(self, ctx: PartiQLParser.LimitClauseContext) -> Any: limit_text = ctx.exprSelect().getText() try: limit_value = int(limit_text) - self._parse_result.limit_value = limit_value + self._query_parse_result.limit_value = limit_value _logger.debug(f"Extracted limit value: {limit_value}") except ValueError as e: _logger.warning(f"Invalid LIMIT value '{limit_text}': {e}") @@ -316,7 +256,7 @@ def visitOffsetByClause(self, ctx: PartiQLParser.OffsetByClauseContext) -> Any: offset_text = ctx.exprSelect().getText() try: offset_value = int(offset_text) - self._parse_result.offset_value = offset_value + self._query_parse_result.offset_value = offset_value _logger.debug(f"Extracted offset value: {offset_value}") except ValueError as e: _logger.warning(f"Invalid OFFSET value '{offset_text}': {e}") diff --git a/pymongosql/sql/builder.py b/pymongosql/sql/builder.py index 6f6771f..66ef501 100644 --- a/pymongosql/sql/builder.py +++ b/pymongosql/sql/builder.py @@ -1,7 +1,17 @@ # -*- coding: utf-8 -*- import logging from dataclasses import dataclass -from typing import Any, Dict, Optional +from typing import TYPE_CHECKING, Any, Dict, Optional, Union + +if TYPE_CHECKING: + from .delete_builder import DeleteExecutionPlan + from .delete_handler import DeleteParseResult + from .insert_builder import InsertExecutionPlan + from .insert_handler import InsertParseResult + from .query_builder import QueryExecutionPlan + from .query_handler import QueryParseResult + from .update_builder import UpdateExecutionPlan + from .update_handler import UpdateParseResult _logger = logging.getLogger(__name__) @@ -66,7 +76,106 @@ def create_update_builder(): return MongoUpdateBuilder() +class ExecutionPlanBuilder: + """Builder class to create execution plans from parse results. + + This class decouples the AST visitor from execution plan creation, + providing a clean separation between parsing and plan generation. + """ + + @staticmethod + def build_from_parse_result( + parse_result: Union["QueryParseResult", "InsertParseResult", "DeleteParseResult", "UpdateParseResult"], + operation: str, + ) -> Union["QueryExecutionPlan", "InsertExecutionPlan", "DeleteExecutionPlan", "UpdateExecutionPlan"]: + """Build an execution plan from a parse result based on the operation type. + + Args: + parse_result: The parse result from the AST visitor + operation: The operation type ('select', 'insert', 'delete', or 'update') + + Returns: + The appropriate execution plan for the operation + + Raises: + SqlSyntaxError: If the parse result is invalid or plan generation fails + """ + if operation == "insert": + return ExecutionPlanBuilder._build_insert_plan(parse_result) + elif operation == "delete": + return ExecutionPlanBuilder._build_delete_plan(parse_result) + elif operation == "update": + return ExecutionPlanBuilder._build_update_plan(parse_result) + else: # Default to SELECT/query + return ExecutionPlanBuilder._build_query_plan(parse_result) + + @staticmethod + def _build_query_plan(parse_result: "QueryParseResult") -> "QueryExecutionPlan": + """Build a query execution plan from SELECT parsing.""" + builder = BuilderFactory.create_query_builder().collection(parse_result.collection) + + builder.filter(parse_result.filter_conditions).project(parse_result.projection).column_aliases( + parse_result.column_aliases + ).sort(parse_result.sort_fields).limit(parse_result.limit_value).skip(parse_result.offset_value) + + return builder.build() + + @staticmethod + def _build_insert_plan(parse_result: "InsertParseResult") -> "InsertExecutionPlan": + """Build an INSERT execution plan from INSERT parsing.""" + from ..error import SqlSyntaxError + + if parse_result.has_errors: + raise SqlSyntaxError(parse_result.error_message or "INSERT parsing failed") + + builder = BuilderFactory.create_insert_builder().collection(parse_result.collection) + + documents = parse_result.insert_documents or [] + builder.insert_documents(documents) + + if parse_result.parameter_style: + builder.parameter_style(parse_result.parameter_style) + + if parse_result.parameter_count > 0: + builder.parameter_count(parse_result.parameter_count) + + return builder.build() + + @staticmethod + def _build_delete_plan(parse_result: "DeleteParseResult") -> "DeleteExecutionPlan": + """Build a DELETE execution plan from DELETE parsing.""" + _logger.debug( + f"Building DELETE plan with collection: {parse_result.collection}, " + f"filters: {parse_result.filter_conditions}" + ) + builder = BuilderFactory.create_delete_builder().collection(parse_result.collection) + + if parse_result.filter_conditions: + builder.filter_conditions(parse_result.filter_conditions) + + return builder.build() + + @staticmethod + def _build_update_plan(parse_result: "UpdateParseResult") -> "UpdateExecutionPlan": + """Build an UPDATE execution plan from UPDATE parsing.""" + _logger.debug( + f"Building UPDATE plan with collection: {parse_result.collection}, " + f"update_fields: {parse_result.update_fields}, " + f"filters: {parse_result.filter_conditions}" + ) + builder = BuilderFactory.create_update_builder().collection(parse_result.collection) + + if parse_result.update_fields: + builder.update_fields(parse_result.update_fields) + + if parse_result.filter_conditions: + builder.filter_conditions(parse_result.filter_conditions) + + return builder.build() + + __all__ = [ "ExecutionPlan", "BuilderFactory", + "ExecutionPlanBuilder", ] diff --git a/pymongosql/sql/handler.py b/pymongosql/sql/handler.py index f4f9622..cafb08d 100644 --- a/pymongosql/sql/handler.py +++ b/pymongosql/sql/handler.py @@ -2,8 +2,10 @@ import logging import re from abc import ABC, abstractmethod -from dataclasses import dataclass, field -from typing import Any, Dict, List, Optional, Tuple +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple + +if TYPE_CHECKING: + from .query_handler import QueryParseResult _logger = logging.getLogger(__name__) @@ -25,61 +27,6 @@ } -@dataclass -class QueryParseResult: - """Result container for query (SELECT) expression parsing and visitor state management""" - - # Core parsing fields - filter_conditions: Dict[str, Any] = field(default_factory=dict) # Unified filter field for all MongoDB conditions - has_errors: bool = False - error_message: Optional[str] = None - - # Visitor parsing state fields - collection: Optional[str] = None - projection: Dict[str, Any] = field(default_factory=dict) - column_aliases: Dict[str, str] = field(default_factory=dict) # Maps field_name -> alias - sort_fields: List[Dict[str, int]] = field(default_factory=list) - limit_value: Optional[int] = None - offset_value: Optional[int] = None - - # Subquery info (for wrapped subqueries, e.g., Superset outering) - subquery_plan: Optional[Any] = None - subquery_alias: Optional[str] = None - - # Factory methods for different use cases - @classmethod - def for_visitor(cls) -> "QueryParseResult": - """Create QueryParseResult for visitor parsing""" - return cls() - - def merge_expression(self, other: "QueryParseResult") -> "QueryParseResult": - """Merge expression results from another QueryParseResult""" - if other.has_errors: - self.has_errors = True - self.error_message = other.error_message - - # Merge filter conditions intelligently - if other.filter_conditions: - if not self.filter_conditions: - self.filter_conditions = other.filter_conditions - else: - # If both have filters, combine them with $and - self.filter_conditions = {"$and": [self.filter_conditions, other.filter_conditions]} - - return self - - # Backward compatibility properties - @property - def mongo_filter(self) -> Dict[str, Any]: - """Backward compatibility property for mongo_filter""" - return self.filter_conditions - - @mongo_filter.setter - def mongo_filter(self, value: Dict[str, Any]): - """Backward compatibility setter for mongo_filter""" - self.filter_conditions = value - - class ContextUtilsMixin: """Mixin providing common context utility methods""" @@ -219,7 +166,7 @@ def can_handle(self, ctx: Any) -> bool: """Check if this handler can process the given context""" pass - def handle(self, ctx: Any, parse_result: Optional["QueryParseResult"] = None) -> Any: + def handle(self, ctx: Any, parse_result: Optional[Any] = None) -> Any: """Handle the context and return appropriate result""" # Default implementation for expression handlers if parse_result is None: @@ -227,11 +174,11 @@ def handle(self, ctx: Any, parse_result: Optional["QueryParseResult"] = None) -> else: return self.handle_visitor(ctx, parse_result) - def handle_expression(self, ctx: Any) -> QueryParseResult: + def handle_expression(self, ctx: Any) -> Any: """Handle expression parsing (to be overridden by expression handlers)""" raise NotImplementedError("Expression handlers must implement handle_expression") - def handle_visitor(self, ctx: Any, parse_result: "QueryParseResult") -> Any: + def handle_visitor(self, ctx: Any, parse_result: Optional[Any] = None) -> Any: """Handle visitor operations (to be overridden by visitor handlers)""" raise NotImplementedError("Visitor handlers must implement handle_visitor") @@ -260,8 +207,10 @@ def can_handle(self, ctx: Any) -> bool: hasattr(ctx, "comparisonOperator") or self._is_comparison_context(ctx) or self._has_comparison_pattern(ctx) ) - def handle_expression(self, ctx: Any) -> QueryParseResult: + def handle_expression(self, ctx: Any) -> "QueryParseResult": """Convert comparison expression to MongoDB filter""" + from .query_handler import QueryParseResult + operation_id = id(ctx) self._log_operation_start("comparison_parsing", ctx, operation_id) @@ -562,8 +511,10 @@ def _is_logical_context(self, ctx: Any) -> bool: except Exception: return False - def handle_expression(self, ctx: Any) -> QueryParseResult: + def handle_expression(self, ctx: Any) -> "QueryParseResult": """Convert logical expression to MongoDB filter""" + from .query_handler import QueryParseResult + operation_id = id(ctx) self._log_operation_start("logical_parsing", ctx, operation_id) @@ -745,8 +696,10 @@ def can_handle(self, ctx: Any) -> bool: """Check if context represents a function call""" return hasattr(ctx, "functionName") or self._is_function_context(ctx) - def handle_expression(self, ctx: Any) -> QueryParseResult: + def handle_expression(self, ctx: Any) -> "QueryParseResult": """Handle function expressions""" + from .query_handler import QueryParseResult + operation_id = id(ctx) self._log_operation_start("function_parsing", ctx, operation_id) diff --git a/pymongosql/sql/parser.py b/pymongosql/sql/parser.py index 5dfe491..33dc607 100644 --- a/pymongosql/sql/parser.py +++ b/pymongosql/sql/parser.py @@ -8,6 +8,7 @@ from ..error import SqlSyntaxError from .ast import MongoSQLLexer, MongoSQLParser, MongoSQLParserVisitor +from .builder import ExecutionPlanBuilder from .delete_builder import DeleteExecutionPlan from .insert_builder import InsertExecutionPlan from .query_builder import QueryExecutionPlan @@ -139,7 +140,11 @@ def get_execution_plan( try: self._visitor = MongoSQLParserVisitor() self._visitor.visit(self._ast) - execution_plan = self._visitor.parse_to_execution_plan() + + # Use ExecutionPlanBuilder to create the plan from parse result + execution_plan = ExecutionPlanBuilder.build_from_parse_result( + self._visitor.parse_result, self._visitor.current_operation + ) if not execution_plan.validate(): raise SqlSyntaxError("Generated execution plan is invalid") From a5231cb5f8fefdaa731bf16d467d604293607f18 Mon Sep 17 00:00:00 2001 From: Peng Ren Date: Tue, 30 Dec 2025 15:43:25 -0500 Subject: [PATCH 2/5] Added column list in INSERT grammar --- pymongosql/sql/partiql/PartiQLParser.g4 | 9 +- pymongosql/sql/partiql/PartiQLParser.py | 4456 +++++++++-------- .../sql/partiql/PartiQLParserListener.py | 9 + .../sql/partiql/PartiQLParserVisitor.py | 5 + 4 files changed, 2317 insertions(+), 2162 deletions(-) diff --git a/pymongosql/sql/partiql/PartiQLParser.g4 b/pymongosql/sql/partiql/PartiQLParser.g4 index dba60c8..bc8328a 100644 --- a/pymongosql/sql/partiql/PartiQLParser.g4 +++ b/pymongosql/sql/partiql/PartiQLParser.g4 @@ -167,6 +167,11 @@ insertCommandReturning // See the Grammar at https://github.com/partiql/partiql-docs/blob/main/RFCs/0011-partiql-insert.md#2-proposed-grammar-and-semantics insertStatement : INSERT INTO symbolPrimitive asIdent? value=expr onConflict? + | INSERT INTO symbolPrimitive columnList? values onConflict? + ; + +columnList + : PAREN_LEFT columnName ( COMMA columnName )* PAREN_RIGHT ; onConflict @@ -711,12 +716,12 @@ trimFunction dateFunction : func=(DATE_ADD|DATE_DIFF) PAREN_LEFT dt=IDENTIFIER COMMA expr COMMA expr PAREN_RIGHT; -// SQL-99 10.4 — ::= +// SQL-99 10.4 � ::= functionCall : functionName PAREN_LEFT ( expr ( COMMA expr )* )? PAREN_RIGHT ; -// SQL-99 10.4 — ::= [ ] +// SQL-99 10.4 � ::= [ ] functionName : (qualifier+=symbolPrimitive PERIOD)* name=( CHAR_LENGTH | CHARACTER_LENGTH | OCTET_LENGTH | BIT_LENGTH | UPPER | LOWER | SIZE | EXISTS | COUNT ) # FunctionNameReserved | (qualifier+=symbolPrimitive PERIOD)* name=symbolPrimitive # FunctionNameSymbol diff --git a/pymongosql/sql/partiql/PartiQLParser.py b/pymongosql/sql/partiql/PartiQLParser.py index 4eafe5d..8fbef32 100644 --- a/pymongosql/sql/partiql/PartiQLParser.py +++ b/pymongosql/sql/partiql/PartiQLParser.py @@ -10,7 +10,7 @@ def serializedATN(): return [ - 4,1,310,1801,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6, + 4,1,310,1826,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6, 7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7, 13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2, 20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7, @@ -32,152 +32,155 @@ def serializedATN(): 7,120,2,121,7,121,2,122,7,122,2,123,7,123,2,124,7,124,2,125,7,125, 2,126,7,126,2,127,7,127,2,128,7,128,2,129,7,129,2,130,7,130,2,131, 7,131,2,132,7,132,2,133,7,133,2,134,7,134,2,135,7,135,2,136,7,136, - 2,137,7,137,2,138,7,138,1,0,1,0,1,0,1,0,1,0,5,0,284,8,0,10,0,12, - 0,287,9,0,1,0,1,0,3,0,291,8,0,3,0,293,8,0,1,0,1,0,1,0,1,1,1,1,3, - 1,300,8,1,1,1,1,1,3,1,304,8,1,1,1,1,1,3,1,308,8,1,1,1,1,1,3,1,312, - 8,1,3,1,314,8,1,1,2,1,2,1,2,1,3,1,3,1,3,1,4,1,4,1,4,1,5,1,5,1,5, - 1,6,1,6,1,7,1,7,1,8,1,8,1,8,1,8,1,8,5,8,337,8,8,10,8,12,8,340,9, - 8,3,8,342,8,8,1,9,1,9,1,9,5,9,347,8,9,10,9,12,9,350,9,9,1,9,1,9, - 1,10,1,10,1,11,1,11,1,12,1,12,1,13,1,13,1,14,1,14,3,14,364,8,14, - 1,15,1,15,1,15,1,15,1,15,1,15,1,15,3,15,373,8,15,1,15,1,15,1,15, - 1,15,1,15,1,15,1,15,1,15,5,15,383,8,15,10,15,12,15,386,9,15,1,15, - 1,15,3,15,390,8,15,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16, - 3,16,401,8,16,1,17,1,17,1,17,5,17,406,8,17,10,17,12,17,409,9,17, - 1,18,1,18,1,18,5,18,414,8,18,10,18,12,18,417,9,18,1,19,1,19,3,19, - 421,8,19,1,19,1,19,1,20,1,20,1,20,3,20,428,8,20,1,21,1,21,4,21,432, - 8,21,11,21,12,21,433,1,21,3,21,437,8,21,1,21,3,21,440,8,21,1,21, - 1,21,3,21,444,8,21,1,21,4,21,447,8,21,11,21,12,21,448,1,21,3,21, - 452,8,21,1,21,1,21,1,21,3,21,457,8,21,1,22,1,22,1,22,1,22,1,22,1, - 22,3,22,465,8,22,1,23,1,23,5,23,469,8,23,10,23,12,23,472,9,23,1, - 24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,3,24,484,8,24,1, - 25,1,25,1,25,1,25,3,25,490,8,25,1,25,1,25,1,26,1,26,1,26,1,26,3, - 26,498,8,26,1,26,1,26,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,28,1, - 28,1,28,3,28,512,8,28,1,28,3,28,515,8,28,1,28,3,28,518,8,28,1,29, - 1,29,1,29,1,29,3,29,524,8,29,1,29,1,29,3,29,528,8,29,1,30,1,30,1, - 30,3,30,533,8,30,1,30,1,30,1,31,1,31,1,31,1,31,1,31,1,31,1,31,3, - 31,544,8,31,1,31,3,31,547,8,31,1,32,1,32,1,32,1,32,1,32,1,32,1,32, - 1,33,1,33,1,33,1,33,5,33,560,8,33,10,33,12,33,563,9,33,1,33,1,33, - 1,33,1,33,1,33,3,33,570,8,33,1,34,1,34,1,35,1,35,1,35,1,35,1,35, - 1,35,1,35,1,35,3,35,582,8,35,1,36,1,36,1,36,3,36,587,8,36,1,37,1, - 37,1,37,3,37,592,8,37,1,38,1,38,1,38,1,39,1,39,1,39,1,39,5,39,601, - 8,39,10,39,12,39,604,9,39,1,40,1,40,1,40,1,40,1,41,1,41,1,41,3,41, - 613,8,41,1,41,3,41,616,8,41,1,42,1,42,1,42,1,42,5,42,622,8,42,10, - 42,12,42,625,9,42,1,43,1,43,1,43,1,43,1,43,1,43,3,43,633,8,43,1, - 44,1,44,1,44,3,44,638,8,44,1,44,3,44,641,8,44,1,44,3,44,644,8,44, - 1,44,1,44,1,44,1,44,3,44,650,8,44,1,45,1,45,1,45,1,46,1,46,3,46, - 657,8,46,1,46,1,46,1,46,3,46,662,8,46,1,46,1,46,1,46,3,46,667,8, - 46,1,46,1,46,1,46,1,46,1,46,1,46,1,46,3,46,676,8,46,1,47,1,47,1, - 47,5,47,681,8,47,10,47,12,47,684,9,47,1,48,1,48,3,48,688,8,48,1, - 48,3,48,691,8,48,1,49,1,49,1,50,1,50,1,50,1,50,5,50,699,8,50,10, - 50,12,50,702,9,50,1,51,1,51,1,51,1,51,1,52,1,52,1,52,1,52,1,52,5, - 52,713,8,52,10,52,12,52,716,9,52,1,53,1,53,3,53,720,8,53,1,53,1, - 53,3,53,724,8,53,1,54,1,54,3,54,728,8,54,1,54,1,54,1,54,1,54,5,54, - 734,8,54,10,54,12,54,737,9,54,1,54,3,54,740,8,54,1,55,1,55,1,55, - 1,55,1,56,1,56,1,56,3,56,749,8,56,1,57,1,57,1,57,3,57,754,8,57,1, - 57,3,57,757,8,57,1,57,1,57,1,58,1,58,1,58,1,58,1,58,5,58,766,8,58, - 10,58,12,58,769,9,58,1,59,1,59,1,59,1,59,1,59,5,59,776,8,59,10,59, - 12,59,779,9,59,1,60,1,60,1,60,1,61,1,61,1,61,1,61,5,61,788,8,61, - 10,61,12,61,791,9,61,1,62,1,62,4,62,795,8,62,11,62,12,62,796,1,63, - 1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,1,63,3,63, - 812,8,63,1,64,1,64,1,64,1,65,1,65,1,65,1,66,1,66,1,66,1,67,1,67, - 1,67,1,68,3,68,827,8,68,1,68,1,68,1,69,3,69,832,8,69,1,69,1,69,1, - 69,5,69,837,8,69,10,69,12,69,840,9,69,1,70,3,70,843,8,70,1,70,3, - 70,846,8,70,1,70,5,70,849,8,70,10,70,12,70,852,9,70,1,71,1,71,1, - 71,3,71,857,8,71,1,72,1,72,1,72,1,72,3,72,863,8,72,1,72,1,72,1,72, - 3,72,868,8,72,3,72,870,8,72,1,73,1,73,1,73,1,74,1,74,1,75,1,75,3, - 75,879,8,75,1,75,1,75,3,75,883,8,75,1,75,3,75,886,8,75,1,75,1,75, - 1,76,1,76,3,76,892,8,76,1,76,1,76,3,76,896,8,76,3,76,898,8,76,1, - 77,1,77,3,77,902,8,77,1,77,3,77,905,8,77,1,77,4,77,908,8,77,11,77, - 12,77,909,1,77,3,77,913,8,77,1,77,1,77,3,77,917,8,77,1,77,1,77,3, - 77,921,8,77,1,77,3,77,924,8,77,1,77,4,77,927,8,77,11,77,12,77,928, - 1,77,3,77,932,8,77,1,77,1,77,3,77,936,8,77,3,77,938,8,77,1,78,1, - 78,1,78,1,78,1,78,3,78,945,8,78,1,78,3,78,948,8,78,1,79,1,79,1,79, - 1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79, - 1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79,1,79, - 1,79,1,79,1,79,1,79,1,79,3,79,984,8,79,1,80,1,80,3,80,988,8,80,1, - 80,1,80,3,80,992,8,80,1,80,3,80,995,8,80,1,80,1,80,1,81,1,81,1,81, - 1,81,1,81,1,81,5,81,1005,8,81,10,81,12,81,1008,9,81,1,82,1,82,1, - 82,1,82,1,82,1,82,5,82,1016,8,82,10,82,12,82,1019,9,82,1,83,1,83, - 1,83,3,83,1024,8,83,1,84,1,84,1,84,1,84,1,84,1,84,3,84,1032,8,84, - 1,85,1,85,1,85,1,85,1,85,1,85,3,85,1040,8,85,1,85,1,85,3,85,1044, - 8,85,3,85,1046,8,85,1,86,1,86,1,86,1,86,1,86,1,86,3,86,1054,8,86, - 1,86,1,86,3,86,1058,8,86,1,86,1,86,1,86,1,86,1,86,1,86,1,86,1,86, - 3,86,1068,8,86,1,86,1,86,1,86,1,86,5,86,1074,8,86,10,86,12,86,1077, - 9,86,1,87,1,87,3,87,1081,8,87,1,88,1,88,1,88,1,88,1,88,3,88,1088, - 8,88,1,88,3,88,1091,8,88,1,88,3,88,1094,8,88,1,88,1,88,3,88,1098, - 8,88,1,88,3,88,1101,8,88,1,88,3,88,1104,8,88,3,88,1106,8,88,1,89, - 1,89,1,89,3,89,1111,8,89,1,89,3,89,1114,8,89,1,89,3,89,1117,8,89, - 1,90,1,90,1,90,1,90,1,90,3,90,1124,8,90,1,91,1,91,1,91,1,92,1,92, - 1,92,3,92,1132,8,92,1,92,1,92,3,92,1136,8,92,1,92,1,92,3,92,1140, - 8,92,1,92,3,92,1143,8,92,1,93,1,93,1,94,1,94,1,94,1,94,1,94,3,94, - 1152,8,94,1,94,1,94,3,94,1156,8,94,1,94,1,94,1,94,3,94,1161,8,94, - 1,94,1,94,3,94,1165,8,94,1,94,1,94,1,94,3,94,1170,8,94,1,94,1,94, - 3,94,1174,8,94,1,94,5,94,1177,8,94,10,94,12,94,1180,9,94,1,95,1, - 95,3,95,1184,8,95,1,95,1,95,3,95,1188,8,95,1,95,3,95,1191,8,95,1, - 95,3,95,1194,8,95,1,95,3,95,1197,8,95,1,95,3,95,1200,8,95,1,95,3, - 95,1203,8,95,1,95,3,95,1206,8,95,1,95,3,95,1209,8,95,1,96,1,96,1, - 96,1,96,1,96,1,96,5,96,1217,8,96,10,96,12,96,1220,9,96,1,97,1,97, - 1,97,1,97,1,97,1,97,5,97,1228,8,97,10,97,12,97,1231,9,97,1,98,1, - 98,1,98,3,98,1236,8,98,1,99,1,99,1,99,1,99,1,99,1,99,1,99,1,99,1, - 99,3,99,1247,8,99,1,99,1,99,1,99,3,99,1252,8,99,1,99,1,99,1,99,1, - 99,1,99,1,99,1,99,3,99,1261,8,99,1,99,1,99,1,99,1,99,3,99,1267,8, - 99,1,99,1,99,1,99,1,99,3,99,1273,8,99,1,99,1,99,3,99,1277,8,99,1, - 99,1,99,1,99,1,99,1,99,5,99,1284,8,99,10,99,12,99,1287,9,99,1,100, - 1,100,1,100,1,100,1,100,1,100,5,100,1295,8,100,10,100,12,100,1298, - 9,100,1,101,1,101,1,101,1,101,1,101,1,101,5,101,1306,8,101,10,101, - 12,101,1309,9,101,1,102,1,102,1,102,1,102,1,102,1,102,5,102,1317, - 8,102,10,102,12,102,1320,9,102,1,103,1,103,1,103,3,103,1325,8,103, - 1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104, - 1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,1,104,3,104, - 1348,8,104,1,104,1,104,4,104,1352,8,104,11,104,12,104,1353,5,104, - 1356,8,104,10,104,12,104,1359,9,104,1,105,1,105,1,105,1,105,1,105, - 1,105,1,105,1,105,1,105,1,105,1,105,3,105,1372,8,105,1,106,1,106, - 1,106,1,106,1,106,1,106,1,106,1,107,1,107,1,107,1,107,1,107,5,107, - 1386,8,107,10,107,12,107,1389,9,107,1,107,1,107,1,108,1,108,3,108, - 1395,8,108,1,108,1,108,1,108,1,108,1,108,4,108,1402,8,108,11,108, - 12,108,1403,1,108,1,108,3,108,1408,8,108,1,108,1,108,1,109,1,109, - 1,109,1,109,5,109,1416,8,109,10,109,12,109,1419,9,109,1,110,1,110, - 1,110,1,110,5,110,1425,8,110,10,110,12,110,1428,9,110,1,110,1,110, - 1,111,1,111,1,111,1,111,4,111,1436,8,111,11,111,12,111,1437,1,111, - 1,111,1,112,1,112,1,112,1,112,1,112,5,112,1447,8,112,10,112,12,112, - 1450,9,112,3,112,1452,8,112,1,112,1,112,1,113,1,113,1,113,1,113, - 1,113,1,113,1,113,3,113,1463,8,113,3,113,1465,8,113,1,113,1,113, - 1,113,1,113,1,113,1,113,1,113,1,113,1,113,3,113,1476,8,113,3,113, - 1478,8,113,1,113,1,113,3,113,1482,8,113,1,114,1,114,1,114,1,114, - 1,114,1,114,1,114,1,114,1,114,1,114,1,114,1,114,1,114,1,114,3,114, - 1498,8,114,1,115,1,115,1,115,1,115,1,115,1,115,1,115,1,115,1,115, - 3,115,1509,8,115,1,115,1,115,1,115,1,115,1,115,1,115,1,115,1,115, - 1,115,1,115,1,115,3,115,1522,8,115,1,115,1,115,3,115,1526,8,115, - 1,116,1,116,1,116,1,116,1,116,1,116,1,116,3,116,1535,8,116,1,116, - 1,116,1,116,3,116,1540,8,116,1,117,1,117,1,117,1,117,1,117,1,117, - 1,117,3,117,1549,8,117,3,117,1551,8,117,1,117,1,117,1,117,1,118, - 1,118,1,118,1,118,1,118,1,118,1,118,1,119,1,119,1,119,1,119,1,119, - 1,119,1,119,1,120,1,120,1,120,1,120,1,120,1,120,1,120,1,121,1,121, - 1,121,1,121,1,121,1,121,1,121,1,122,1,122,1,122,3,122,1587,8,122, - 1,122,3,122,1590,8,122,1,122,3,122,1593,8,122,1,122,1,122,1,122, - 1,123,1,123,1,123,1,123,1,123,1,123,1,123,1,123,1,123,1,124,1,124, - 1,124,1,124,1,124,5,124,1612,8,124,10,124,12,124,1615,9,124,3,124, - 1617,8,124,1,124,1,124,1,125,1,125,1,125,5,125,1624,8,125,10,125, - 12,125,1627,9,125,1,125,1,125,1,125,1,125,5,125,1633,8,125,10,125, - 12,125,1636,9,125,1,125,3,125,1639,8,125,1,126,1,126,1,126,1,126, - 1,126,1,126,1,126,1,126,1,126,1,126,1,126,3,126,1652,8,126,1,127, - 1,127,1,127,1,127,1,127,1,127,1,128,1,128,1,128,1,128,1,129,1,129, - 1,130,3,130,1667,8,130,1,130,1,130,3,130,1671,8,130,1,130,3,130, - 1674,8,130,1,131,1,131,1,132,1,132,3,132,1680,8,132,1,133,1,133, - 1,133,1,133,5,133,1686,8,133,10,133,12,133,1689,9,133,3,133,1691, - 8,133,1,133,1,133,1,134,1,134,1,134,1,134,5,134,1699,8,134,10,134, - 12,134,1702,9,134,3,134,1704,8,134,1,134,1,134,1,135,1,135,1,135, - 1,135,5,135,1712,8,135,10,135,12,135,1715,9,135,3,135,1717,8,135, - 1,135,1,135,1,136,1,136,1,136,1,136,1,137,1,137,1,137,1,137,1,137, - 1,137,1,137,1,137,1,137,1,137,1,137,1,137,1,137,1,137,3,137,1739, - 8,137,1,137,1,137,1,137,3,137,1744,8,137,1,137,1,137,1,137,1,137, - 1,137,3,137,1751,8,137,1,137,1,137,1,137,3,137,1756,8,137,1,137, - 3,137,1759,8,137,1,138,1,138,1,138,1,138,1,138,1,138,1,138,3,138, - 1768,8,138,1,138,1,138,1,138,1,138,1,138,3,138,1775,8,138,1,138, - 1,138,1,138,1,138,1,138,3,138,1782,8,138,1,138,3,138,1785,8,138, - 1,138,1,138,1,138,1,138,3,138,1791,8,138,1,138,1,138,1,138,3,138, - 1796,8,138,1,138,3,138,1799,8,138,1,138,0,11,162,164,172,188,192, - 194,198,200,202,204,208,139,0,2,4,6,8,10,12,14,16,18,20,22,24,26, + 2,137,7,137,2,138,7,138,2,139,7,139,1,0,1,0,1,0,1,0,1,0,5,0,286, + 8,0,10,0,12,0,289,9,0,1,0,1,0,3,0,293,8,0,3,0,295,8,0,1,0,1,0,1, + 0,1,1,1,1,3,1,302,8,1,1,1,1,1,3,1,306,8,1,1,1,1,1,3,1,310,8,1,1, + 1,1,1,3,1,314,8,1,3,1,316,8,1,1,2,1,2,1,2,1,3,1,3,1,3,1,4,1,4,1, + 4,1,5,1,5,1,5,1,6,1,6,1,7,1,7,1,8,1,8,1,8,1,8,1,8,5,8,339,8,8,10, + 8,12,8,342,9,8,3,8,344,8,8,1,9,1,9,1,9,5,9,349,8,9,10,9,12,9,352, + 9,9,1,9,1,9,1,10,1,10,1,11,1,11,1,12,1,12,1,13,1,13,1,14,1,14,3, + 14,366,8,14,1,15,1,15,1,15,1,15,1,15,1,15,1,15,3,15,375,8,15,1,15, + 1,15,1,15,1,15,1,15,1,15,1,15,1,15,5,15,385,8,15,10,15,12,15,388, + 9,15,1,15,1,15,3,15,392,8,15,1,16,1,16,1,16,1,16,1,16,1,16,1,16, + 1,16,1,16,3,16,403,8,16,1,17,1,17,1,17,5,17,408,8,17,10,17,12,17, + 411,9,17,1,18,1,18,1,18,5,18,416,8,18,10,18,12,18,419,9,18,1,19, + 1,19,3,19,423,8,19,1,19,1,19,1,20,1,20,1,20,3,20,430,8,20,1,21,1, + 21,4,21,434,8,21,11,21,12,21,435,1,21,3,21,439,8,21,1,21,3,21,442, + 8,21,1,21,1,21,3,21,446,8,21,1,21,4,21,449,8,21,11,21,12,21,450, + 1,21,3,21,454,8,21,1,21,1,21,1,21,3,21,459,8,21,1,22,1,22,1,22,1, + 22,1,22,1,22,3,22,467,8,22,1,23,1,23,5,23,471,8,23,10,23,12,23,474, + 9,23,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,3,24,486, + 8,24,1,25,1,25,1,25,1,25,3,25,492,8,25,1,25,1,25,1,26,1,26,1,26, + 1,26,3,26,500,8,26,1,26,1,26,1,27,1,27,1,27,1,28,1,28,1,28,1,28, + 1,28,1,28,1,28,3,28,514,8,28,1,28,3,28,517,8,28,1,28,3,28,520,8, + 28,1,29,1,29,1,29,1,29,3,29,526,8,29,1,29,1,29,3,29,530,8,29,1,29, + 1,29,1,29,1,29,3,29,536,8,29,1,29,1,29,3,29,540,8,29,3,29,542,8, + 29,1,30,1,30,1,30,1,30,5,30,548,8,30,10,30,12,30,551,9,30,1,30,1, + 30,1,31,1,31,1,31,3,31,558,8,31,1,31,1,31,1,32,1,32,1,32,1,32,1, + 32,1,32,1,32,3,32,569,8,32,1,32,3,32,572,8,32,1,33,1,33,1,33,1,33, + 1,33,1,33,1,33,1,34,1,34,1,34,1,34,5,34,585,8,34,10,34,12,34,588, + 9,34,1,34,1,34,1,34,1,34,1,34,3,34,595,8,34,1,35,1,35,1,36,1,36, + 1,36,1,36,1,36,1,36,1,36,1,36,3,36,607,8,36,1,37,1,37,1,37,3,37, + 612,8,37,1,38,1,38,1,38,3,38,617,8,38,1,39,1,39,1,39,1,40,1,40,1, + 40,1,40,5,40,626,8,40,10,40,12,40,629,9,40,1,41,1,41,1,41,1,41,1, + 42,1,42,1,42,3,42,638,8,42,1,42,3,42,641,8,42,1,43,1,43,1,43,1,43, + 5,43,647,8,43,10,43,12,43,650,9,43,1,44,1,44,1,44,1,44,1,44,1,44, + 3,44,658,8,44,1,45,1,45,1,45,3,45,663,8,45,1,45,3,45,666,8,45,1, + 45,3,45,669,8,45,1,45,1,45,1,45,1,45,3,45,675,8,45,1,46,1,46,1,46, + 1,47,1,47,3,47,682,8,47,1,47,1,47,1,47,3,47,687,8,47,1,47,1,47,1, + 47,3,47,692,8,47,1,47,1,47,1,47,1,47,1,47,1,47,1,47,3,47,701,8,47, + 1,48,1,48,1,48,5,48,706,8,48,10,48,12,48,709,9,48,1,49,1,49,3,49, + 713,8,49,1,49,3,49,716,8,49,1,50,1,50,1,51,1,51,1,51,1,51,5,51,724, + 8,51,10,51,12,51,727,9,51,1,52,1,52,1,52,1,52,1,53,1,53,1,53,1,53, + 1,53,5,53,738,8,53,10,53,12,53,741,9,53,1,54,1,54,3,54,745,8,54, + 1,54,1,54,3,54,749,8,54,1,55,1,55,3,55,753,8,55,1,55,1,55,1,55,1, + 55,5,55,759,8,55,10,55,12,55,762,9,55,1,55,3,55,765,8,55,1,56,1, + 56,1,56,1,56,1,57,1,57,1,57,3,57,774,8,57,1,58,1,58,1,58,3,58,779, + 8,58,1,58,3,58,782,8,58,1,58,1,58,1,59,1,59,1,59,1,59,1,59,5,59, + 791,8,59,10,59,12,59,794,9,59,1,60,1,60,1,60,1,60,1,60,5,60,801, + 8,60,10,60,12,60,804,9,60,1,61,1,61,1,61,1,62,1,62,1,62,1,62,5,62, + 813,8,62,10,62,12,62,816,9,62,1,63,1,63,4,63,820,8,63,11,63,12,63, + 821,1,64,1,64,1,64,1,64,1,64,1,64,1,64,1,64,1,64,1,64,1,64,1,64, + 1,64,3,64,837,8,64,1,65,1,65,1,65,1,66,1,66,1,66,1,67,1,67,1,67, + 1,68,1,68,1,68,1,69,3,69,852,8,69,1,69,1,69,1,70,3,70,857,8,70,1, + 70,1,70,1,70,5,70,862,8,70,10,70,12,70,865,9,70,1,71,3,71,868,8, + 71,1,71,3,71,871,8,71,1,71,5,71,874,8,71,10,71,12,71,877,9,71,1, + 72,1,72,1,72,3,72,882,8,72,1,73,1,73,1,73,1,73,3,73,888,8,73,1,73, + 1,73,1,73,3,73,893,8,73,3,73,895,8,73,1,74,1,74,1,74,1,75,1,75,1, + 76,1,76,3,76,904,8,76,1,76,1,76,3,76,908,8,76,1,76,3,76,911,8,76, + 1,76,1,76,1,77,1,77,3,77,917,8,77,1,77,1,77,3,77,921,8,77,3,77,923, + 8,77,1,78,1,78,3,78,927,8,78,1,78,3,78,930,8,78,1,78,4,78,933,8, + 78,11,78,12,78,934,1,78,3,78,938,8,78,1,78,1,78,3,78,942,8,78,1, + 78,1,78,3,78,946,8,78,1,78,3,78,949,8,78,1,78,4,78,952,8,78,11,78, + 12,78,953,1,78,3,78,957,8,78,1,78,1,78,3,78,961,8,78,3,78,963,8, + 78,1,79,1,79,1,79,1,79,1,79,3,79,970,8,79,1,79,3,79,973,8,79,1,80, + 1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80, + 1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80,1,80, + 1,80,1,80,1,80,1,80,1,80,1,80,1,80,3,80,1009,8,80,1,81,1,81,3,81, + 1013,8,81,1,81,1,81,3,81,1017,8,81,1,81,3,81,1020,8,81,1,81,1,81, + 1,82,1,82,1,82,1,82,1,82,1,82,5,82,1030,8,82,10,82,12,82,1033,9, + 82,1,83,1,83,1,83,1,83,1,83,1,83,5,83,1041,8,83,10,83,12,83,1044, + 9,83,1,84,1,84,1,84,3,84,1049,8,84,1,85,1,85,1,85,1,85,1,85,1,85, + 3,85,1057,8,85,1,86,1,86,1,86,1,86,1,86,1,86,3,86,1065,8,86,1,86, + 1,86,3,86,1069,8,86,3,86,1071,8,86,1,87,1,87,1,87,1,87,1,87,1,87, + 3,87,1079,8,87,1,87,1,87,3,87,1083,8,87,1,87,1,87,1,87,1,87,1,87, + 1,87,1,87,1,87,3,87,1093,8,87,1,87,1,87,1,87,1,87,5,87,1099,8,87, + 10,87,12,87,1102,9,87,1,88,1,88,3,88,1106,8,88,1,89,1,89,1,89,1, + 89,1,89,3,89,1113,8,89,1,89,3,89,1116,8,89,1,89,3,89,1119,8,89,1, + 89,1,89,3,89,1123,8,89,1,89,3,89,1126,8,89,1,89,3,89,1129,8,89,3, + 89,1131,8,89,1,90,1,90,1,90,3,90,1136,8,90,1,90,3,90,1139,8,90,1, + 90,3,90,1142,8,90,1,91,1,91,1,91,1,91,1,91,3,91,1149,8,91,1,92,1, + 92,1,92,1,93,1,93,1,93,3,93,1157,8,93,1,93,1,93,3,93,1161,8,93,1, + 93,1,93,3,93,1165,8,93,1,93,3,93,1168,8,93,1,94,1,94,1,95,1,95,1, + 95,1,95,1,95,3,95,1177,8,95,1,95,1,95,3,95,1181,8,95,1,95,1,95,1, + 95,3,95,1186,8,95,1,95,1,95,3,95,1190,8,95,1,95,1,95,1,95,3,95,1195, + 8,95,1,95,1,95,3,95,1199,8,95,1,95,5,95,1202,8,95,10,95,12,95,1205, + 9,95,1,96,1,96,3,96,1209,8,96,1,96,1,96,3,96,1213,8,96,1,96,3,96, + 1216,8,96,1,96,3,96,1219,8,96,1,96,3,96,1222,8,96,1,96,3,96,1225, + 8,96,1,96,3,96,1228,8,96,1,96,3,96,1231,8,96,1,96,3,96,1234,8,96, + 1,97,1,97,1,97,1,97,1,97,1,97,5,97,1242,8,97,10,97,12,97,1245,9, + 97,1,98,1,98,1,98,1,98,1,98,1,98,5,98,1253,8,98,10,98,12,98,1256, + 9,98,1,99,1,99,1,99,3,99,1261,8,99,1,100,1,100,1,100,1,100,1,100, + 1,100,1,100,1,100,1,100,3,100,1272,8,100,1,100,1,100,1,100,3,100, + 1277,8,100,1,100,1,100,1,100,1,100,1,100,1,100,1,100,3,100,1286, + 8,100,1,100,1,100,1,100,1,100,3,100,1292,8,100,1,100,1,100,1,100, + 1,100,3,100,1298,8,100,1,100,1,100,3,100,1302,8,100,1,100,1,100, + 1,100,1,100,1,100,5,100,1309,8,100,10,100,12,100,1312,9,100,1,101, + 1,101,1,101,1,101,1,101,1,101,5,101,1320,8,101,10,101,12,101,1323, + 9,101,1,102,1,102,1,102,1,102,1,102,1,102,5,102,1331,8,102,10,102, + 12,102,1334,9,102,1,103,1,103,1,103,1,103,1,103,1,103,5,103,1342, + 8,103,10,103,12,103,1345,9,103,1,104,1,104,1,104,3,104,1350,8,104, + 1,105,1,105,1,105,1,105,1,105,1,105,1,105,1,105,1,105,1,105,1,105, + 1,105,1,105,1,105,1,105,1,105,1,105,1,105,1,105,1,105,1,105,3,105, + 1373,8,105,1,105,1,105,4,105,1377,8,105,11,105,12,105,1378,5,105, + 1381,8,105,10,105,12,105,1384,9,105,1,106,1,106,1,106,1,106,1,106, + 1,106,1,106,1,106,1,106,1,106,1,106,3,106,1397,8,106,1,107,1,107, + 1,107,1,107,1,107,1,107,1,107,1,108,1,108,1,108,1,108,1,108,5,108, + 1411,8,108,10,108,12,108,1414,9,108,1,108,1,108,1,109,1,109,3,109, + 1420,8,109,1,109,1,109,1,109,1,109,1,109,4,109,1427,8,109,11,109, + 12,109,1428,1,109,1,109,3,109,1433,8,109,1,109,1,109,1,110,1,110, + 1,110,1,110,5,110,1441,8,110,10,110,12,110,1444,9,110,1,111,1,111, + 1,111,1,111,5,111,1450,8,111,10,111,12,111,1453,9,111,1,111,1,111, + 1,112,1,112,1,112,1,112,4,112,1461,8,112,11,112,12,112,1462,1,112, + 1,112,1,113,1,113,1,113,1,113,1,113,5,113,1472,8,113,10,113,12,113, + 1475,9,113,3,113,1477,8,113,1,113,1,113,1,114,1,114,1,114,1,114, + 1,114,1,114,1,114,3,114,1488,8,114,3,114,1490,8,114,1,114,1,114, + 1,114,1,114,1,114,1,114,1,114,1,114,1,114,3,114,1501,8,114,3,114, + 1503,8,114,1,114,1,114,3,114,1507,8,114,1,115,1,115,1,115,1,115, + 1,115,1,115,1,115,1,115,1,115,1,115,1,115,1,115,1,115,1,115,3,115, + 1523,8,115,1,116,1,116,1,116,1,116,1,116,1,116,1,116,1,116,1,116, + 3,116,1534,8,116,1,116,1,116,1,116,1,116,1,116,1,116,1,116,1,116, + 1,116,1,116,1,116,3,116,1547,8,116,1,116,1,116,3,116,1551,8,116, + 1,117,1,117,1,117,1,117,1,117,1,117,1,117,3,117,1560,8,117,1,117, + 1,117,1,117,3,117,1565,8,117,1,118,1,118,1,118,1,118,1,118,1,118, + 1,118,3,118,1574,8,118,3,118,1576,8,118,1,118,1,118,1,118,1,119, + 1,119,1,119,1,119,1,119,1,119,1,119,1,120,1,120,1,120,1,120,1,120, + 1,120,1,120,1,121,1,121,1,121,1,121,1,121,1,121,1,121,1,122,1,122, + 1,122,1,122,1,122,1,122,1,122,1,123,1,123,1,123,3,123,1612,8,123, + 1,123,3,123,1615,8,123,1,123,3,123,1618,8,123,1,123,1,123,1,123, + 1,124,1,124,1,124,1,124,1,124,1,124,1,124,1,124,1,124,1,125,1,125, + 1,125,1,125,1,125,5,125,1637,8,125,10,125,12,125,1640,9,125,3,125, + 1642,8,125,1,125,1,125,1,126,1,126,1,126,5,126,1649,8,126,10,126, + 12,126,1652,9,126,1,126,1,126,1,126,1,126,5,126,1658,8,126,10,126, + 12,126,1661,9,126,1,126,3,126,1664,8,126,1,127,1,127,1,127,1,127, + 1,127,1,127,1,127,1,127,1,127,1,127,1,127,3,127,1677,8,127,1,128, + 1,128,1,128,1,128,1,128,1,128,1,129,1,129,1,129,1,129,1,130,1,130, + 1,131,3,131,1692,8,131,1,131,1,131,3,131,1696,8,131,1,131,3,131, + 1699,8,131,1,132,1,132,1,133,1,133,3,133,1705,8,133,1,134,1,134, + 1,134,1,134,5,134,1711,8,134,10,134,12,134,1714,9,134,3,134,1716, + 8,134,1,134,1,134,1,135,1,135,1,135,1,135,5,135,1724,8,135,10,135, + 12,135,1727,9,135,3,135,1729,8,135,1,135,1,135,1,136,1,136,1,136, + 1,136,5,136,1737,8,136,10,136,12,136,1740,9,136,3,136,1742,8,136, + 1,136,1,136,1,137,1,137,1,137,1,137,1,138,1,138,1,138,1,138,1,138, + 1,138,1,138,1,138,1,138,1,138,1,138,1,138,1,138,1,138,3,138,1764, + 8,138,1,138,1,138,1,138,3,138,1769,8,138,1,138,1,138,1,138,1,138, + 1,138,3,138,1776,8,138,1,138,1,138,1,138,3,138,1781,8,138,1,138, + 3,138,1784,8,138,1,139,1,139,1,139,1,139,1,139,1,139,1,139,3,139, + 1793,8,139,1,139,1,139,1,139,1,139,1,139,3,139,1800,8,139,1,139, + 1,139,1,139,1,139,1,139,3,139,1807,8,139,1,139,3,139,1810,8,139, + 1,139,1,139,1,139,1,139,3,139,1816,8,139,1,139,1,139,1,139,3,139, + 1821,8,139,1,139,3,139,1824,8,139,1,139,0,11,164,166,174,190,194, + 196,200,202,204,206,210,140,0,2,4,6,8,10,12,14,16,18,20,22,24,26, 28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70, 72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102,104,106,108,110, 112,114,116,118,120,122,124,126,128,130,132,134,136,138,140,142, @@ -185,565 +188,574 @@ def serializedATN(): 176,178,180,182,184,186,188,190,192,194,196,198,200,202,204,206, 208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,238, 240,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270, - 272,274,276,0,21,1,0,303,304,2,0,4,4,247,247,1,0,248,249,2,0,4,4, - 67,67,2,0,11,11,62,62,2,0,90,90,123,123,2,0,4,4,8,8,2,0,271,271, - 277,277,2,0,281,284,286,287,2,0,279,279,285,285,1,0,271,272,2,0, - 273,274,277,277,1,0,266,267,7,0,8,8,15,15,44,44,75,75,131,132,189, - 189,196,196,1,0,230,231,1,0,86,87,8,0,19,19,28,29,44,44,82,82,129, - 129,145,145,187,187,213,213,9,0,8,8,26,27,53,53,113,114,141,141, - 170,170,188,188,236,236,251,268,3,0,26,27,91,91,220,220,2,0,55,56, - 144,144,1,0,201,202,1963,0,292,1,0,0,0,2,313,1,0,0,0,4,315,1,0,0, - 0,6,318,1,0,0,0,8,321,1,0,0,0,10,324,1,0,0,0,12,327,1,0,0,0,14,329, - 1,0,0,0,16,331,1,0,0,0,18,348,1,0,0,0,20,353,1,0,0,0,22,355,1,0, - 0,0,24,357,1,0,0,0,26,359,1,0,0,0,28,363,1,0,0,0,30,389,1,0,0,0, - 32,400,1,0,0,0,34,402,1,0,0,0,36,410,1,0,0,0,38,420,1,0,0,0,40,427, - 1,0,0,0,42,456,1,0,0,0,44,464,1,0,0,0,46,466,1,0,0,0,48,483,1,0, - 0,0,50,485,1,0,0,0,52,493,1,0,0,0,54,501,1,0,0,0,56,504,1,0,0,0, - 58,519,1,0,0,0,60,529,1,0,0,0,62,536,1,0,0,0,64,548,1,0,0,0,66,569, - 1,0,0,0,68,571,1,0,0,0,70,581,1,0,0,0,72,583,1,0,0,0,74,588,1,0, - 0,0,76,593,1,0,0,0,78,596,1,0,0,0,80,605,1,0,0,0,82,609,1,0,0,0, - 84,617,1,0,0,0,86,632,1,0,0,0,88,649,1,0,0,0,90,651,1,0,0,0,92,675, - 1,0,0,0,94,677,1,0,0,0,96,685,1,0,0,0,98,692,1,0,0,0,100,694,1,0, - 0,0,102,703,1,0,0,0,104,707,1,0,0,0,106,717,1,0,0,0,108,725,1,0, - 0,0,110,741,1,0,0,0,112,745,1,0,0,0,114,750,1,0,0,0,116,760,1,0, - 0,0,118,770,1,0,0,0,120,780,1,0,0,0,122,783,1,0,0,0,124,792,1,0, - 0,0,126,811,1,0,0,0,128,813,1,0,0,0,130,816,1,0,0,0,132,819,1,0, - 0,0,134,822,1,0,0,0,136,826,1,0,0,0,138,831,1,0,0,0,140,842,1,0, - 0,0,142,856,1,0,0,0,144,869,1,0,0,0,146,871,1,0,0,0,148,874,1,0, - 0,0,150,876,1,0,0,0,152,897,1,0,0,0,154,937,1,0,0,0,156,947,1,0, - 0,0,158,983,1,0,0,0,160,985,1,0,0,0,162,998,1,0,0,0,164,1009,1,0, - 0,0,166,1023,1,0,0,0,168,1031,1,0,0,0,170,1045,1,0,0,0,172,1053, - 1,0,0,0,174,1080,1,0,0,0,176,1105,1,0,0,0,178,1107,1,0,0,0,180,1123, - 1,0,0,0,182,1125,1,0,0,0,184,1142,1,0,0,0,186,1144,1,0,0,0,188,1146, - 1,0,0,0,190,1208,1,0,0,0,192,1210,1,0,0,0,194,1221,1,0,0,0,196,1235, - 1,0,0,0,198,1237,1,0,0,0,200,1288,1,0,0,0,202,1299,1,0,0,0,204,1310, - 1,0,0,0,206,1324,1,0,0,0,208,1347,1,0,0,0,210,1371,1,0,0,0,212,1373, - 1,0,0,0,214,1380,1,0,0,0,216,1392,1,0,0,0,218,1411,1,0,0,0,220,1420, - 1,0,0,0,222,1431,1,0,0,0,224,1441,1,0,0,0,226,1481,1,0,0,0,228,1497, - 1,0,0,0,230,1525,1,0,0,0,232,1539,1,0,0,0,234,1541,1,0,0,0,236,1555, - 1,0,0,0,238,1562,1,0,0,0,240,1569,1,0,0,0,242,1576,1,0,0,0,244,1583, - 1,0,0,0,246,1597,1,0,0,0,248,1606,1,0,0,0,250,1638,1,0,0,0,252,1651, - 1,0,0,0,254,1653,1,0,0,0,256,1659,1,0,0,0,258,1663,1,0,0,0,260,1673, - 1,0,0,0,262,1675,1,0,0,0,264,1679,1,0,0,0,266,1681,1,0,0,0,268,1694, - 1,0,0,0,270,1707,1,0,0,0,272,1720,1,0,0,0,274,1758,1,0,0,0,276,1798, - 1,0,0,0,278,290,5,83,0,0,279,280,5,294,0,0,280,285,3,4,2,0,281,282, - 5,270,0,0,282,284,3,4,2,0,283,281,1,0,0,0,284,287,1,0,0,0,285,283, - 1,0,0,0,285,286,1,0,0,0,286,288,1,0,0,0,287,285,1,0,0,0,288,289, - 5,295,0,0,289,291,1,0,0,0,290,279,1,0,0,0,290,291,1,0,0,0,291,293, - 1,0,0,0,292,278,1,0,0,0,292,293,1,0,0,0,293,294,1,0,0,0,294,295, - 3,2,1,0,295,296,5,0,0,1,296,1,1,0,0,0,297,299,3,14,7,0,298,300,5, - 297,0,0,299,298,1,0,0,0,299,300,1,0,0,0,300,314,1,0,0,0,301,303, - 3,42,21,0,302,304,5,297,0,0,303,302,1,0,0,0,303,304,1,0,0,0,304, - 314,1,0,0,0,305,307,3,28,14,0,306,308,5,297,0,0,307,306,1,0,0,0, - 307,308,1,0,0,0,308,314,1,0,0,0,309,311,3,16,8,0,310,312,5,297,0, - 0,311,310,1,0,0,0,311,312,1,0,0,0,312,314,1,0,0,0,313,297,1,0,0, - 0,313,301,1,0,0,0,313,305,1,0,0,0,313,309,1,0,0,0,314,3,1,0,0,0, - 315,316,5,303,0,0,316,317,5,303,0,0,317,5,1,0,0,0,318,319,5,10,0, - 0,319,320,3,12,6,0,320,7,1,0,0,0,321,322,5,13,0,0,322,323,3,12,6, - 0,323,9,1,0,0,0,324,325,5,20,0,0,325,326,3,12,6,0,326,11,1,0,0,0, - 327,328,7,0,0,0,328,13,1,0,0,0,329,330,3,186,93,0,330,15,1,0,0,0, - 331,332,5,80,0,0,332,341,3,186,93,0,333,338,3,186,93,0,334,335,5, - 270,0,0,335,337,3,186,93,0,336,334,1,0,0,0,337,340,1,0,0,0,338,336, - 1,0,0,0,338,339,1,0,0,0,339,342,1,0,0,0,340,338,1,0,0,0,341,333, - 1,0,0,0,341,342,1,0,0,0,342,17,1,0,0,0,343,344,3,12,6,0,344,345, - 5,299,0,0,345,347,1,0,0,0,346,343,1,0,0,0,347,350,1,0,0,0,348,346, - 1,0,0,0,348,349,1,0,0,0,349,351,1,0,0,0,350,348,1,0,0,0,351,352, - 3,12,6,0,352,19,1,0,0,0,353,354,3,12,6,0,354,21,1,0,0,0,355,356, - 3,12,6,0,356,23,1,0,0,0,357,358,3,12,6,0,358,25,1,0,0,0,359,360, - 3,12,6,0,360,27,1,0,0,0,361,364,3,30,15,0,362,364,3,32,16,0,363, - 361,1,0,0,0,363,362,1,0,0,0,364,29,1,0,0,0,365,366,5,45,0,0,366, - 367,5,198,0,0,367,372,3,18,9,0,368,369,5,294,0,0,369,370,3,34,17, - 0,370,371,5,295,0,0,371,373,1,0,0,0,372,368,1,0,0,0,372,373,1,0, - 0,0,373,390,1,0,0,0,374,375,5,45,0,0,375,376,5,242,0,0,376,377,5, - 147,0,0,377,378,3,12,6,0,378,379,5,294,0,0,379,384,3,46,23,0,380, - 381,5,270,0,0,381,383,3,46,23,0,382,380,1,0,0,0,383,386,1,0,0,0, - 384,382,1,0,0,0,384,385,1,0,0,0,385,387,1,0,0,0,386,384,1,0,0,0, - 387,388,5,295,0,0,388,390,1,0,0,0,389,365,1,0,0,0,389,374,1,0,0, - 0,390,31,1,0,0,0,391,392,5,70,0,0,392,393,5,198,0,0,393,401,3,18, - 9,0,394,395,5,70,0,0,395,396,5,242,0,0,396,397,3,12,6,0,397,398, - 5,147,0,0,398,399,3,12,6,0,399,401,1,0,0,0,400,391,1,0,0,0,400,394, - 1,0,0,0,401,33,1,0,0,0,402,407,3,36,18,0,403,404,5,270,0,0,404,406, - 3,36,18,0,405,403,1,0,0,0,406,409,1,0,0,0,407,405,1,0,0,0,407,408, - 1,0,0,0,408,35,1,0,0,0,409,407,1,0,0,0,410,411,3,24,12,0,411,415, - 3,276,138,0,412,414,3,38,19,0,413,412,1,0,0,0,414,417,1,0,0,0,415, - 413,1,0,0,0,415,416,1,0,0,0,416,37,1,0,0,0,417,415,1,0,0,0,418,419, - 5,39,0,0,419,421,3,26,13,0,420,418,1,0,0,0,420,421,1,0,0,0,421,422, - 1,0,0,0,422,423,3,40,20,0,423,39,1,0,0,0,424,425,5,140,0,0,425,428, - 5,141,0,0,426,428,5,141,0,0,427,424,1,0,0,0,427,426,1,0,0,0,428, - 41,1,0,0,0,429,431,3,76,38,0,430,432,3,44,22,0,431,430,1,0,0,0,432, - 433,1,0,0,0,433,431,1,0,0,0,433,434,1,0,0,0,434,436,1,0,0,0,435, - 437,3,90,45,0,436,435,1,0,0,0,436,437,1,0,0,0,437,439,1,0,0,0,438, - 440,3,84,42,0,439,438,1,0,0,0,439,440,1,0,0,0,440,457,1,0,0,0,441, - 443,3,128,64,0,442,444,3,90,45,0,443,442,1,0,0,0,443,444,1,0,0,0, - 444,446,1,0,0,0,445,447,3,44,22,0,446,445,1,0,0,0,447,448,1,0,0, - 0,448,446,1,0,0,0,448,449,1,0,0,0,449,451,1,0,0,0,450,452,3,84,42, - 0,451,450,1,0,0,0,451,452,1,0,0,0,452,457,1,0,0,0,453,457,3,82,41, - 0,454,457,3,56,28,0,455,457,3,44,22,0,456,429,1,0,0,0,456,441,1, - 0,0,0,456,453,1,0,0,0,456,454,1,0,0,0,456,455,1,0,0,0,457,43,1,0, - 0,0,458,465,3,58,29,0,459,465,3,62,31,0,460,465,3,78,39,0,461,465, - 3,50,25,0,462,465,3,54,27,0,463,465,3,52,26,0,464,458,1,0,0,0,464, - 459,1,0,0,0,464,460,1,0,0,0,464,461,1,0,0,0,464,462,1,0,0,0,464, - 463,1,0,0,0,465,45,1,0,0,0,466,470,3,12,6,0,467,469,3,48,24,0,468, - 467,1,0,0,0,469,472,1,0,0,0,470,468,1,0,0,0,470,471,1,0,0,0,471, - 47,1,0,0,0,472,470,1,0,0,0,473,474,5,290,0,0,474,475,3,274,137,0, - 475,476,5,291,0,0,476,484,1,0,0,0,477,478,5,290,0,0,478,479,3,12, - 6,0,479,480,5,291,0,0,480,484,1,0,0,0,481,482,5,299,0,0,482,484, - 3,12,6,0,483,473,1,0,0,0,483,477,1,0,0,0,483,481,1,0,0,0,484,49, - 1,0,0,0,485,486,5,173,0,0,486,487,5,117,0,0,487,489,3,12,6,0,488, - 490,3,6,3,0,489,488,1,0,0,0,489,490,1,0,0,0,490,491,1,0,0,0,491, - 492,3,186,93,0,492,51,1,0,0,0,493,494,5,214,0,0,494,495,5,117,0, - 0,495,497,3,12,6,0,496,498,3,6,3,0,497,496,1,0,0,0,497,498,1,0,0, - 0,498,499,1,0,0,0,499,500,3,186,93,0,500,53,1,0,0,0,501,502,5,241, - 0,0,502,503,3,46,23,0,503,55,1,0,0,0,504,505,5,112,0,0,505,506,5, - 117,0,0,506,507,3,46,23,0,507,508,5,218,0,0,508,511,3,186,93,0,509, - 510,5,13,0,0,510,512,3,186,93,0,511,509,1,0,0,0,511,512,1,0,0,0, - 512,514,1,0,0,0,513,515,3,64,32,0,514,513,1,0,0,0,514,515,1,0,0, - 0,515,517,1,0,0,0,516,518,3,84,42,0,517,516,1,0,0,0,517,518,1,0, - 0,0,518,57,1,0,0,0,519,520,5,112,0,0,520,521,5,117,0,0,521,523,3, - 12,6,0,522,524,3,6,3,0,523,522,1,0,0,0,523,524,1,0,0,0,524,525,1, - 0,0,0,525,527,3,186,93,0,526,528,3,60,30,0,527,526,1,0,0,0,527,528, - 1,0,0,0,528,59,1,0,0,0,529,530,5,147,0,0,530,532,5,244,0,0,531,533, - 3,66,33,0,532,531,1,0,0,0,532,533,1,0,0,0,533,534,1,0,0,0,534,535, - 3,70,35,0,535,61,1,0,0,0,536,537,5,112,0,0,537,538,5,117,0,0,538, - 539,3,46,23,0,539,540,5,218,0,0,540,543,3,186,93,0,541,542,5,13, - 0,0,542,544,3,186,93,0,543,541,1,0,0,0,543,544,1,0,0,0,544,546,1, - 0,0,0,545,547,3,64,32,0,546,545,1,0,0,0,546,547,1,0,0,0,547,63,1, - 0,0,0,548,549,5,147,0,0,549,550,5,244,0,0,550,551,5,225,0,0,551, - 552,3,186,93,0,552,553,5,245,0,0,553,554,5,250,0,0,554,65,1,0,0, - 0,555,556,5,294,0,0,556,561,3,12,6,0,557,558,5,270,0,0,558,560,3, - 12,6,0,559,557,1,0,0,0,560,563,1,0,0,0,561,559,1,0,0,0,561,562,1, - 0,0,0,562,564,1,0,0,0,563,561,1,0,0,0,564,565,5,295,0,0,565,570, - 1,0,0,0,566,567,5,147,0,0,567,568,5,39,0,0,568,570,3,68,34,0,569, - 555,1,0,0,0,569,566,1,0,0,0,570,67,1,0,0,0,571,572,3,12,6,0,572, - 69,1,0,0,0,573,574,5,245,0,0,574,582,5,250,0,0,575,576,5,245,0,0, - 576,577,5,173,0,0,577,582,3,72,36,0,578,579,5,245,0,0,579,580,5, - 212,0,0,580,582,3,74,37,0,581,573,1,0,0,0,581,575,1,0,0,0,581,578, - 1,0,0,0,582,71,1,0,0,0,583,586,5,79,0,0,584,585,5,225,0,0,585,587, - 3,186,93,0,586,584,1,0,0,0,586,587,1,0,0,0,587,73,1,0,0,0,588,591, - 5,79,0,0,589,590,5,225,0,0,590,592,3,186,93,0,591,589,1,0,0,0,591, - 592,1,0,0,0,592,75,1,0,0,0,593,594,5,212,0,0,594,595,3,176,88,0, - 595,77,1,0,0,0,596,597,5,185,0,0,597,602,3,80,40,0,598,599,5,270, - 0,0,599,601,3,80,40,0,600,598,1,0,0,0,601,604,1,0,0,0,602,600,1, - 0,0,0,602,603,1,0,0,0,603,79,1,0,0,0,604,602,1,0,0,0,605,606,3,46, - 23,0,606,607,5,283,0,0,607,608,3,186,93,0,608,81,1,0,0,0,609,610, - 5,61,0,0,610,612,3,88,44,0,611,613,3,90,45,0,612,611,1,0,0,0,612, - 613,1,0,0,0,613,615,1,0,0,0,614,616,3,84,42,0,615,614,1,0,0,0,615, - 616,1,0,0,0,616,83,1,0,0,0,617,618,5,246,0,0,618,623,3,86,43,0,619, - 620,5,270,0,0,620,622,3,86,43,0,621,619,1,0,0,0,622,625,1,0,0,0, - 623,621,1,0,0,0,623,624,1,0,0,0,624,85,1,0,0,0,625,623,1,0,0,0,626, - 627,7,1,0,0,627,628,7,2,0,0,628,633,5,277,0,0,629,630,7,1,0,0,630, - 631,7,2,0,0,631,633,3,186,93,0,632,626,1,0,0,0,632,629,1,0,0,0,633, - 87,1,0,0,0,634,635,5,95,0,0,635,637,3,46,23,0,636,638,3,6,3,0,637, - 636,1,0,0,0,637,638,1,0,0,0,638,640,1,0,0,0,639,641,3,8,4,0,640, - 639,1,0,0,0,640,641,1,0,0,0,641,643,1,0,0,0,642,644,3,10,5,0,643, - 642,1,0,0,0,643,644,1,0,0,0,644,650,1,0,0,0,645,646,5,95,0,0,646, - 647,3,46,23,0,647,648,3,12,6,0,648,650,1,0,0,0,649,634,1,0,0,0,649, - 645,1,0,0,0,650,89,1,0,0,0,651,652,5,225,0,0,652,653,3,186,93,0, - 653,91,1,0,0,0,654,656,5,182,0,0,655,657,3,98,49,0,656,655,1,0,0, - 0,656,657,1,0,0,0,657,658,1,0,0,0,658,676,5,277,0,0,659,661,5,182, - 0,0,660,662,3,98,49,0,661,660,1,0,0,0,661,662,1,0,0,0,662,663,1, - 0,0,0,663,676,3,94,47,0,664,666,5,182,0,0,665,667,3,98,49,0,666, - 665,1,0,0,0,666,667,1,0,0,0,667,668,1,0,0,0,668,669,5,218,0,0,669, - 676,3,186,93,0,670,671,5,237,0,0,671,672,3,186,93,0,672,673,5,13, - 0,0,673,674,3,186,93,0,674,676,1,0,0,0,675,654,1,0,0,0,675,659,1, - 0,0,0,675,664,1,0,0,0,675,670,1,0,0,0,676,93,1,0,0,0,677,682,3,96, - 48,0,678,679,5,270,0,0,679,681,3,96,48,0,680,678,1,0,0,0,681,684, - 1,0,0,0,682,680,1,0,0,0,682,683,1,0,0,0,683,95,1,0,0,0,684,682,1, - 0,0,0,685,690,3,186,93,0,686,688,5,10,0,0,687,686,1,0,0,0,687,688, - 1,0,0,0,688,689,1,0,0,0,689,691,3,12,6,0,690,687,1,0,0,0,690,691, - 1,0,0,0,691,97,1,0,0,0,692,693,7,3,0,0,693,99,1,0,0,0,694,695,5, - 243,0,0,695,700,3,102,51,0,696,697,5,270,0,0,697,699,3,102,51,0, - 698,696,1,0,0,0,699,702,1,0,0,0,700,698,1,0,0,0,700,701,1,0,0,0, - 701,101,1,0,0,0,702,700,1,0,0,0,703,704,3,186,93,0,704,705,5,10, - 0,0,705,706,3,12,6,0,706,103,1,0,0,0,707,708,5,152,0,0,708,709,5, - 20,0,0,709,714,3,106,53,0,710,711,5,270,0,0,711,713,3,106,53,0,712, - 710,1,0,0,0,713,716,1,0,0,0,714,712,1,0,0,0,714,715,1,0,0,0,715, - 105,1,0,0,0,716,714,1,0,0,0,717,719,3,186,93,0,718,720,7,4,0,0,719, - 718,1,0,0,0,719,720,1,0,0,0,720,723,1,0,0,0,721,722,5,142,0,0,722, - 724,7,5,0,0,723,721,1,0,0,0,723,724,1,0,0,0,724,107,1,0,0,0,725, - 727,5,102,0,0,726,728,5,158,0,0,727,726,1,0,0,0,727,728,1,0,0,0, - 728,729,1,0,0,0,729,730,5,20,0,0,730,735,3,112,56,0,731,732,5,270, - 0,0,732,734,3,112,56,0,733,731,1,0,0,0,734,737,1,0,0,0,735,733,1, - 0,0,0,735,736,1,0,0,0,736,739,1,0,0,0,737,735,1,0,0,0,738,740,3, - 110,55,0,739,738,1,0,0,0,739,740,1,0,0,0,740,109,1,0,0,0,741,742, - 5,102,0,0,742,743,5,10,0,0,743,744,3,12,6,0,744,111,1,0,0,0,745, - 748,3,190,95,0,746,747,5,10,0,0,747,749,3,12,6,0,748,746,1,0,0,0, - 748,749,1,0,0,0,749,113,1,0,0,0,750,751,5,232,0,0,751,753,5,294, - 0,0,752,754,3,116,58,0,753,752,1,0,0,0,753,754,1,0,0,0,754,756,1, - 0,0,0,755,757,3,118,59,0,756,755,1,0,0,0,756,757,1,0,0,0,757,758, - 1,0,0,0,758,759,5,295,0,0,759,115,1,0,0,0,760,761,5,233,0,0,761, - 762,5,20,0,0,762,767,3,186,93,0,763,764,5,270,0,0,764,766,3,186, - 93,0,765,763,1,0,0,0,766,769,1,0,0,0,767,765,1,0,0,0,767,768,1,0, - 0,0,768,117,1,0,0,0,769,767,1,0,0,0,770,771,5,152,0,0,771,772,5, - 20,0,0,772,777,3,106,53,0,773,774,5,270,0,0,774,776,3,106,53,0,775, - 773,1,0,0,0,776,779,1,0,0,0,777,775,1,0,0,0,777,778,1,0,0,0,778, - 119,1,0,0,0,779,777,1,0,0,0,780,781,5,103,0,0,781,782,3,190,95,0, - 782,121,1,0,0,0,783,784,5,78,0,0,784,789,3,124,62,0,785,786,5,270, - 0,0,786,788,3,124,62,0,787,785,1,0,0,0,788,791,1,0,0,0,789,787,1, - 0,0,0,789,790,1,0,0,0,790,123,1,0,0,0,791,789,1,0,0,0,792,794,3, - 12,6,0,793,795,3,126,63,0,794,793,1,0,0,0,795,796,1,0,0,0,796,794, - 1,0,0,0,796,797,1,0,0,0,797,125,1,0,0,0,798,799,5,299,0,0,799,812, - 3,12,6,0,800,801,5,290,0,0,801,802,5,300,0,0,802,812,5,291,0,0,803, - 804,5,290,0,0,804,805,5,301,0,0,805,812,5,291,0,0,806,807,5,290, - 0,0,807,808,5,277,0,0,808,812,5,291,0,0,809,810,5,299,0,0,810,812, - 5,277,0,0,811,798,1,0,0,0,811,800,1,0,0,0,811,803,1,0,0,0,811,806, - 1,0,0,0,811,809,1,0,0,0,812,127,1,0,0,0,813,814,5,95,0,0,814,815, - 3,172,86,0,815,129,1,0,0,0,816,817,5,225,0,0,817,818,3,190,95,0, - 818,131,1,0,0,0,819,820,5,240,0,0,820,821,3,190,95,0,821,133,1,0, - 0,0,822,823,5,239,0,0,823,824,3,190,95,0,824,135,1,0,0,0,825,827, - 3,144,72,0,826,825,1,0,0,0,826,827,1,0,0,0,827,828,1,0,0,0,828,829, - 3,140,70,0,829,137,1,0,0,0,830,832,3,144,72,0,831,830,1,0,0,0,831, - 832,1,0,0,0,832,833,1,0,0,0,833,838,3,140,70,0,834,835,5,270,0,0, - 835,837,3,140,70,0,836,834,1,0,0,0,837,840,1,0,0,0,838,836,1,0,0, - 0,838,839,1,0,0,0,839,139,1,0,0,0,840,838,1,0,0,0,841,843,3,148, - 74,0,842,841,1,0,0,0,842,843,1,0,0,0,843,845,1,0,0,0,844,846,3,146, - 73,0,845,844,1,0,0,0,845,846,1,0,0,0,846,850,1,0,0,0,847,849,3,142, - 71,0,848,847,1,0,0,0,849,852,1,0,0,0,850,848,1,0,0,0,850,851,1,0, - 0,0,851,141,1,0,0,0,852,850,1,0,0,0,853,857,3,150,75,0,854,857,3, - 152,76,0,855,857,3,154,77,0,856,853,1,0,0,0,856,854,1,0,0,0,856, - 855,1,0,0,0,857,143,1,0,0,0,858,859,7,6,0,0,859,870,5,186,0,0,860, - 862,5,8,0,0,861,863,5,301,0,0,862,861,1,0,0,0,862,863,1,0,0,0,863, - 870,1,0,0,0,864,865,5,186,0,0,865,867,5,301,0,0,866,868,5,102,0, - 0,867,866,1,0,0,0,867,868,1,0,0,0,868,870,1,0,0,0,869,858,1,0,0, - 0,869,860,1,0,0,0,869,864,1,0,0,0,870,145,1,0,0,0,871,872,3,12,6, - 0,872,873,5,283,0,0,873,147,1,0,0,0,874,875,5,303,0,0,875,149,1, - 0,0,0,876,878,5,294,0,0,877,879,3,12,6,0,878,877,1,0,0,0,878,879, - 1,0,0,0,879,882,1,0,0,0,880,881,5,296,0,0,881,883,3,162,81,0,882, - 880,1,0,0,0,882,883,1,0,0,0,883,885,1,0,0,0,884,886,3,90,45,0,885, - 884,1,0,0,0,885,886,1,0,0,0,886,887,1,0,0,0,887,888,5,295,0,0,888, - 151,1,0,0,0,889,891,3,158,79,0,890,892,3,156,78,0,891,890,1,0,0, - 0,891,892,1,0,0,0,892,898,1,0,0,0,893,895,3,170,85,0,894,896,3,156, - 78,0,895,894,1,0,0,0,895,896,1,0,0,0,896,898,1,0,0,0,897,889,1,0, - 0,0,897,893,1,0,0,0,898,153,1,0,0,0,899,901,5,294,0,0,900,902,3, - 148,74,0,901,900,1,0,0,0,901,902,1,0,0,0,902,904,1,0,0,0,903,905, - 3,146,73,0,904,903,1,0,0,0,904,905,1,0,0,0,905,907,1,0,0,0,906,908, - 3,142,71,0,907,906,1,0,0,0,908,909,1,0,0,0,909,907,1,0,0,0,909,910, - 1,0,0,0,910,912,1,0,0,0,911,913,3,90,45,0,912,911,1,0,0,0,912,913, - 1,0,0,0,913,914,1,0,0,0,914,916,5,295,0,0,915,917,3,156,78,0,916, - 915,1,0,0,0,916,917,1,0,0,0,917,938,1,0,0,0,918,920,5,290,0,0,919, - 921,3,148,74,0,920,919,1,0,0,0,920,921,1,0,0,0,921,923,1,0,0,0,922, - 924,3,146,73,0,923,922,1,0,0,0,923,924,1,0,0,0,924,926,1,0,0,0,925, - 927,3,142,71,0,926,925,1,0,0,0,927,928,1,0,0,0,928,926,1,0,0,0,928, - 929,1,0,0,0,929,931,1,0,0,0,930,932,3,90,45,0,931,930,1,0,0,0,931, - 932,1,0,0,0,932,933,1,0,0,0,933,935,5,291,0,0,934,936,3,156,78,0, - 935,934,1,0,0,0,935,936,1,0,0,0,936,938,1,0,0,0,937,899,1,0,0,0, - 937,918,1,0,0,0,938,155,1,0,0,0,939,948,7,7,0,0,940,941,5,292,0, - 0,941,942,5,301,0,0,942,944,5,270,0,0,943,945,5,301,0,0,944,943, - 1,0,0,0,944,945,1,0,0,0,945,946,1,0,0,0,946,948,5,293,0,0,947,939, - 1,0,0,0,947,940,1,0,0,0,948,157,1,0,0,0,949,950,5,272,0,0,950,951, - 3,160,80,0,951,952,5,272,0,0,952,953,5,287,0,0,953,984,1,0,0,0,954, - 955,5,276,0,0,955,956,3,160,80,0,956,957,5,276,0,0,957,984,1,0,0, - 0,958,959,5,286,0,0,959,960,5,272,0,0,960,961,3,160,80,0,961,962, - 5,272,0,0,962,984,1,0,0,0,963,964,5,276,0,0,964,965,3,160,80,0,965, - 966,5,276,0,0,966,967,5,287,0,0,967,984,1,0,0,0,968,969,5,286,0, - 0,969,970,5,276,0,0,970,971,3,160,80,0,971,972,5,276,0,0,972,984, - 1,0,0,0,973,974,5,286,0,0,974,975,5,272,0,0,975,976,3,160,80,0,976, - 977,5,272,0,0,977,978,5,287,0,0,978,984,1,0,0,0,979,980,5,272,0, - 0,980,981,3,160,80,0,981,982,5,272,0,0,982,984,1,0,0,0,983,949,1, - 0,0,0,983,954,1,0,0,0,983,958,1,0,0,0,983,963,1,0,0,0,983,968,1, - 0,0,0,983,973,1,0,0,0,983,979,1,0,0,0,984,159,1,0,0,0,985,987,5, - 290,0,0,986,988,3,12,6,0,987,986,1,0,0,0,987,988,1,0,0,0,988,991, - 1,0,0,0,989,990,5,296,0,0,990,992,3,162,81,0,991,989,1,0,0,0,991, - 992,1,0,0,0,992,994,1,0,0,0,993,995,3,90,45,0,994,993,1,0,0,0,994, - 995,1,0,0,0,995,996,1,0,0,0,996,997,5,291,0,0,997,161,1,0,0,0,998, - 999,6,81,-1,0,999,1000,3,164,82,0,1000,1006,1,0,0,0,1001,1002,10, - 2,0,0,1002,1003,5,278,0,0,1003,1005,3,164,82,0,1004,1001,1,0,0,0, - 1005,1008,1,0,0,0,1006,1004,1,0,0,0,1006,1007,1,0,0,0,1007,163,1, - 0,0,0,1008,1006,1,0,0,0,1009,1010,6,82,-1,0,1010,1011,3,166,83,0, - 1011,1017,1,0,0,0,1012,1013,10,2,0,0,1013,1014,5,279,0,0,1014,1016, - 3,166,83,0,1015,1012,1,0,0,0,1016,1019,1,0,0,0,1017,1015,1,0,0,0, - 1017,1018,1,0,0,0,1018,165,1,0,0,0,1019,1017,1,0,0,0,1020,1021,5, - 280,0,0,1021,1024,3,168,84,0,1022,1024,3,168,84,0,1023,1020,1,0, - 0,0,1023,1022,1,0,0,0,1024,167,1,0,0,0,1025,1032,3,12,6,0,1026,1032, - 5,274,0,0,1027,1028,5,294,0,0,1028,1029,3,162,81,0,1029,1030,5,295, - 0,0,1030,1032,1,0,0,0,1031,1025,1,0,0,0,1031,1026,1,0,0,0,1031,1027, - 1,0,0,0,1032,169,1,0,0,0,1033,1046,5,276,0,0,1034,1035,5,276,0,0, - 1035,1046,5,287,0,0,1036,1037,5,286,0,0,1037,1046,5,276,0,0,1038, - 1040,5,286,0,0,1039,1038,1,0,0,0,1039,1040,1,0,0,0,1040,1041,1,0, - 0,0,1041,1043,5,272,0,0,1042,1044,5,287,0,0,1043,1042,1,0,0,0,1043, - 1044,1,0,0,0,1044,1046,1,0,0,0,1045,1033,1,0,0,0,1045,1034,1,0,0, - 0,1045,1036,1,0,0,0,1045,1039,1,0,0,0,1046,171,1,0,0,0,1047,1048, - 6,86,-1,0,1048,1054,3,174,87,0,1049,1050,5,294,0,0,1050,1051,3,172, - 86,0,1051,1052,5,295,0,0,1052,1054,1,0,0,0,1053,1047,1,0,0,0,1053, - 1049,1,0,0,0,1054,1075,1,0,0,0,1055,1057,10,5,0,0,1056,1058,3,184, - 92,0,1057,1056,1,0,0,0,1057,1058,1,0,0,0,1058,1059,1,0,0,0,1059, - 1060,5,46,0,0,1060,1061,5,120,0,0,1061,1074,3,180,90,0,1062,1063, - 10,4,0,0,1063,1064,5,270,0,0,1064,1074,3,180,90,0,1065,1067,10,3, - 0,0,1066,1068,3,184,92,0,1067,1066,1,0,0,0,1067,1068,1,0,0,0,1068, - 1069,1,0,0,0,1069,1070,5,120,0,0,1070,1071,3,180,90,0,1071,1072, - 3,182,91,0,1072,1074,1,0,0,0,1073,1055,1,0,0,0,1073,1062,1,0,0,0, - 1073,1065,1,0,0,0,1074,1077,1,0,0,0,1075,1073,1,0,0,0,1075,1076, - 1,0,0,0,1076,173,1,0,0,0,1077,1075,1,0,0,0,1078,1081,3,176,88,0, - 1079,1081,3,178,89,0,1080,1078,1,0,0,0,1080,1079,1,0,0,0,1081,175, - 1,0,0,0,1082,1083,3,190,95,0,1083,1084,3,12,6,0,1084,1106,1,0,0, - 0,1085,1087,3,190,95,0,1086,1088,3,6,3,0,1087,1086,1,0,0,0,1087, - 1088,1,0,0,0,1088,1090,1,0,0,0,1089,1091,3,8,4,0,1090,1089,1,0,0, - 0,1090,1091,1,0,0,0,1091,1093,1,0,0,0,1092,1094,3,10,5,0,1093,1092, - 1,0,0,0,1093,1094,1,0,0,0,1094,1106,1,0,0,0,1095,1097,3,256,128, - 0,1096,1098,3,6,3,0,1097,1096,1,0,0,0,1097,1098,1,0,0,0,1098,1100, - 1,0,0,0,1099,1101,3,8,4,0,1100,1099,1,0,0,0,1100,1101,1,0,0,0,1101, - 1103,1,0,0,0,1102,1104,3,10,5,0,1103,1102,1,0,0,0,1103,1104,1,0, - 0,0,1104,1106,1,0,0,0,1105,1082,1,0,0,0,1105,1085,1,0,0,0,1105,1095, - 1,0,0,0,1106,177,1,0,0,0,1107,1108,5,238,0,0,1108,1110,3,186,93, - 0,1109,1111,3,6,3,0,1110,1109,1,0,0,0,1110,1111,1,0,0,0,1111,1113, - 1,0,0,0,1112,1114,3,8,4,0,1113,1112,1,0,0,0,1113,1114,1,0,0,0,1114, - 1116,1,0,0,0,1115,1117,3,10,5,0,1116,1115,1,0,0,0,1116,1117,1,0, - 0,0,1117,179,1,0,0,0,1118,1124,3,174,87,0,1119,1120,5,294,0,0,1120, - 1121,3,172,86,0,1121,1122,5,295,0,0,1122,1124,1,0,0,0,1123,1118, - 1,0,0,0,1123,1119,1,0,0,0,1124,181,1,0,0,0,1125,1126,5,147,0,0,1126, - 1127,3,186,93,0,1127,183,1,0,0,0,1128,1143,5,109,0,0,1129,1131,5, - 125,0,0,1130,1132,5,153,0,0,1131,1130,1,0,0,0,1131,1132,1,0,0,0, - 1132,1143,1,0,0,0,1133,1135,5,176,0,0,1134,1136,5,153,0,0,1135,1134, - 1,0,0,0,1135,1136,1,0,0,0,1136,1143,1,0,0,0,1137,1139,5,96,0,0,1138, - 1140,5,153,0,0,1139,1138,1,0,0,0,1139,1140,1,0,0,0,1140,1143,1,0, - 0,0,1141,1143,5,153,0,0,1142,1128,1,0,0,0,1142,1129,1,0,0,0,1142, - 1133,1,0,0,0,1142,1137,1,0,0,0,1142,1141,1,0,0,0,1143,185,1,0,0, - 0,1144,1145,3,188,94,0,1145,187,1,0,0,0,1146,1147,6,94,-1,0,1147, - 1148,3,190,95,0,1148,1178,1,0,0,0,1149,1151,10,4,0,0,1150,1152,5, - 153,0,0,1151,1150,1,0,0,0,1151,1152,1,0,0,0,1152,1153,1,0,0,0,1153, - 1155,5,76,0,0,1154,1156,7,3,0,0,1155,1154,1,0,0,0,1155,1156,1,0, - 0,0,1156,1157,1,0,0,0,1157,1177,3,190,95,0,1158,1160,10,3,0,0,1159, - 1161,5,153,0,0,1160,1159,1,0,0,0,1160,1161,1,0,0,0,1161,1162,1,0, - 0,0,1162,1164,5,209,0,0,1163,1165,7,3,0,0,1164,1163,1,0,0,0,1164, - 1165,1,0,0,0,1165,1166,1,0,0,0,1166,1177,3,190,95,0,1167,1169,10, - 2,0,0,1168,1170,5,153,0,0,1169,1168,1,0,0,0,1169,1170,1,0,0,0,1170, - 1171,1,0,0,0,1171,1173,5,115,0,0,1172,1174,7,3,0,0,1173,1172,1,0, - 0,0,1173,1174,1,0,0,0,1174,1175,1,0,0,0,1175,1177,3,190,95,0,1176, - 1149,1,0,0,0,1176,1158,1,0,0,0,1176,1167,1,0,0,0,1177,1180,1,0,0, - 0,1178,1176,1,0,0,0,1178,1179,1,0,0,0,1179,189,1,0,0,0,1180,1178, - 1,0,0,0,1181,1183,3,92,46,0,1182,1184,3,122,61,0,1183,1182,1,0,0, - 0,1183,1184,1,0,0,0,1184,1185,1,0,0,0,1185,1187,3,128,64,0,1186, - 1188,3,100,50,0,1187,1186,1,0,0,0,1187,1188,1,0,0,0,1188,1190,1, - 0,0,0,1189,1191,3,130,65,0,1190,1189,1,0,0,0,1190,1191,1,0,0,0,1191, - 1193,1,0,0,0,1192,1194,3,108,54,0,1193,1192,1,0,0,0,1193,1194,1, - 0,0,0,1194,1196,1,0,0,0,1195,1197,3,120,60,0,1196,1195,1,0,0,0,1196, - 1197,1,0,0,0,1197,1199,1,0,0,0,1198,1200,3,104,52,0,1199,1198,1, - 0,0,0,1199,1200,1,0,0,0,1200,1202,1,0,0,0,1201,1203,3,134,67,0,1202, - 1201,1,0,0,0,1202,1203,1,0,0,0,1203,1205,1,0,0,0,1204,1206,3,132, - 66,0,1205,1204,1,0,0,0,1205,1206,1,0,0,0,1206,1209,1,0,0,0,1207, - 1209,3,192,96,0,1208,1181,1,0,0,0,1208,1207,1,0,0,0,1209,191,1,0, - 0,0,1210,1211,6,96,-1,0,1211,1212,3,194,97,0,1212,1218,1,0,0,0,1213, - 1214,10,2,0,0,1214,1215,5,151,0,0,1215,1217,3,194,97,0,1216,1213, - 1,0,0,0,1217,1220,1,0,0,0,1218,1216,1,0,0,0,1218,1219,1,0,0,0,1219, - 193,1,0,0,0,1220,1218,1,0,0,0,1221,1222,6,97,-1,0,1222,1223,3,196, - 98,0,1223,1229,1,0,0,0,1224,1225,10,2,0,0,1225,1226,5,7,0,0,1226, - 1228,3,196,98,0,1227,1224,1,0,0,0,1228,1231,1,0,0,0,1229,1227,1, - 0,0,0,1229,1230,1,0,0,0,1230,195,1,0,0,0,1231,1229,1,0,0,0,1232, - 1233,5,140,0,0,1233,1236,3,196,98,0,1234,1236,3,198,99,0,1235,1232, - 1,0,0,0,1235,1234,1,0,0,0,1236,197,1,0,0,0,1237,1238,6,99,-1,0,1238, - 1239,3,200,100,0,1239,1285,1,0,0,0,1240,1241,10,7,0,0,1241,1242, - 7,8,0,0,1242,1284,3,200,100,0,1243,1244,10,6,0,0,1244,1246,5,118, - 0,0,1245,1247,5,140,0,0,1246,1245,1,0,0,0,1246,1247,1,0,0,0,1247, - 1248,1,0,0,0,1248,1284,3,276,138,0,1249,1251,10,5,0,0,1250,1252, - 5,140,0,0,1251,1250,1,0,0,0,1251,1252,1,0,0,0,1252,1253,1,0,0,0, - 1253,1254,5,106,0,0,1254,1255,5,294,0,0,1255,1256,3,186,93,0,1256, - 1257,5,295,0,0,1257,1284,1,0,0,0,1258,1260,10,4,0,0,1259,1261,5, - 140,0,0,1260,1259,1,0,0,0,1260,1261,1,0,0,0,1261,1262,1,0,0,0,1262, - 1263,5,106,0,0,1263,1284,3,200,100,0,1264,1266,10,3,0,0,1265,1267, - 5,140,0,0,1266,1265,1,0,0,0,1266,1267,1,0,0,0,1267,1268,1,0,0,0, - 1268,1269,5,127,0,0,1269,1272,3,200,100,0,1270,1271,5,74,0,0,1271, - 1273,3,186,93,0,1272,1270,1,0,0,0,1272,1273,1,0,0,0,1273,1284,1, - 0,0,0,1274,1276,10,2,0,0,1275,1277,5,140,0,0,1276,1275,1,0,0,0,1276, - 1277,1,0,0,0,1277,1278,1,0,0,0,1278,1279,5,17,0,0,1279,1280,3,200, - 100,0,1280,1281,5,7,0,0,1281,1282,3,200,100,0,1282,1284,1,0,0,0, - 1283,1240,1,0,0,0,1283,1243,1,0,0,0,1283,1249,1,0,0,0,1283,1258, - 1,0,0,0,1283,1264,1,0,0,0,1283,1274,1,0,0,0,1284,1287,1,0,0,0,1285, - 1283,1,0,0,0,1285,1286,1,0,0,0,1286,199,1,0,0,0,1287,1285,1,0,0, - 0,1288,1289,6,100,-1,0,1289,1290,3,202,101,0,1290,1296,1,0,0,0,1291, - 1292,10,2,0,0,1292,1293,7,9,0,0,1293,1295,3,202,101,0,1294,1291, - 1,0,0,0,1295,1298,1,0,0,0,1296,1294,1,0,0,0,1296,1297,1,0,0,0,1297, - 201,1,0,0,0,1298,1296,1,0,0,0,1299,1300,6,101,-1,0,1300,1301,3,204, - 102,0,1301,1307,1,0,0,0,1302,1303,10,2,0,0,1303,1304,7,10,0,0,1304, - 1306,3,204,102,0,1305,1302,1,0,0,0,1306,1309,1,0,0,0,1307,1305,1, - 0,0,0,1307,1308,1,0,0,0,1308,203,1,0,0,0,1309,1307,1,0,0,0,1310, - 1311,6,102,-1,0,1311,1312,3,206,103,0,1312,1318,1,0,0,0,1313,1314, - 10,2,0,0,1314,1315,7,11,0,0,1315,1317,3,206,103,0,1316,1313,1,0, - 0,0,1317,1320,1,0,0,0,1318,1316,1,0,0,0,1318,1319,1,0,0,0,1319,205, - 1,0,0,0,1320,1318,1,0,0,0,1321,1322,7,10,0,0,1322,1325,3,206,103, - 0,1323,1325,3,208,104,0,1324,1321,1,0,0,0,1324,1323,1,0,0,0,1325, - 207,1,0,0,0,1326,1327,6,104,-1,0,1327,1348,3,210,105,0,1328,1348, - 3,236,118,0,1329,1348,3,224,112,0,1330,1348,3,226,113,0,1331,1348, - 3,228,114,0,1332,1348,3,230,115,0,1333,1348,3,240,120,0,1334,1348, - 3,238,119,0,1335,1348,3,242,121,0,1336,1348,3,214,107,0,1337,1348, - 3,246,123,0,1338,1348,3,232,116,0,1339,1348,3,244,122,0,1340,1348, - 3,248,124,0,1341,1348,3,212,106,0,1342,1348,3,254,127,0,1343,1348, - 3,216,108,0,1344,1348,3,222,111,0,1345,1348,3,218,109,0,1346,1348, - 3,234,117,0,1347,1326,1,0,0,0,1347,1328,1,0,0,0,1347,1329,1,0,0, - 0,1347,1330,1,0,0,0,1347,1331,1,0,0,0,1347,1332,1,0,0,0,1347,1333, - 1,0,0,0,1347,1334,1,0,0,0,1347,1335,1,0,0,0,1347,1336,1,0,0,0,1347, - 1337,1,0,0,0,1347,1338,1,0,0,0,1347,1339,1,0,0,0,1347,1340,1,0,0, - 0,1347,1341,1,0,0,0,1347,1342,1,0,0,0,1347,1343,1,0,0,0,1347,1344, - 1,0,0,0,1347,1345,1,0,0,0,1347,1346,1,0,0,0,1348,1357,1,0,0,0,1349, - 1351,10,6,0,0,1350,1352,3,252,126,0,1351,1350,1,0,0,0,1352,1353, - 1,0,0,0,1353,1351,1,0,0,0,1353,1354,1,0,0,0,1354,1356,1,0,0,0,1355, - 1349,1,0,0,0,1356,1359,1,0,0,0,1357,1355,1,0,0,0,1357,1358,1,0,0, - 0,1358,209,1,0,0,0,1359,1357,1,0,0,0,1360,1361,5,294,0,0,1361,1362, - 3,186,93,0,1362,1363,5,295,0,0,1363,1372,1,0,0,0,1364,1372,5,51, - 0,0,1365,1372,5,48,0,0,1366,1372,3,258,129,0,1367,1372,3,260,130, - 0,1368,1372,3,274,137,0,1369,1372,3,264,132,0,1370,1372,3,270,135, - 0,1371,1360,1,0,0,0,1371,1364,1,0,0,0,1371,1365,1,0,0,0,1371,1366, - 1,0,0,0,1371,1367,1,0,0,0,1371,1368,1,0,0,0,1371,1369,1,0,0,0,1371, - 1370,1,0,0,0,1372,211,1,0,0,0,1373,1374,5,143,0,0,1374,1375,5,294, - 0,0,1375,1376,3,186,93,0,1376,1377,5,270,0,0,1377,1378,3,186,93, - 0,1378,1379,5,295,0,0,1379,213,1,0,0,0,1380,1381,5,32,0,0,1381,1382, - 5,294,0,0,1382,1387,3,186,93,0,1383,1384,5,270,0,0,1384,1386,3,186, - 93,0,1385,1383,1,0,0,0,1386,1389,1,0,0,0,1387,1385,1,0,0,0,1387, - 1388,1,0,0,0,1388,1390,1,0,0,0,1389,1387,1,0,0,0,1390,1391,5,295, - 0,0,1391,215,1,0,0,0,1392,1394,5,23,0,0,1393,1395,3,186,93,0,1394, - 1393,1,0,0,0,1394,1395,1,0,0,0,1395,1401,1,0,0,0,1396,1397,5,223, - 0,0,1397,1398,3,186,93,0,1398,1399,5,200,0,0,1399,1400,3,186,93, - 0,1400,1402,1,0,0,0,1401,1396,1,0,0,0,1402,1403,1,0,0,0,1403,1401, - 1,0,0,0,1403,1404,1,0,0,0,1404,1407,1,0,0,0,1405,1406,5,71,0,0,1406, - 1408,3,186,93,0,1407,1405,1,0,0,0,1407,1408,1,0,0,0,1408,1409,1, - 0,0,0,1409,1410,5,72,0,0,1410,217,1,0,0,0,1411,1412,5,219,0,0,1412, - 1417,3,220,110,0,1413,1414,5,270,0,0,1414,1416,3,220,110,0,1415, - 1413,1,0,0,0,1416,1419,1,0,0,0,1417,1415,1,0,0,0,1417,1418,1,0,0, - 0,1418,219,1,0,0,0,1419,1417,1,0,0,0,1420,1421,5,294,0,0,1421,1426, - 3,186,93,0,1422,1423,5,270,0,0,1423,1425,3,186,93,0,1424,1422,1, - 0,0,0,1425,1428,1,0,0,0,1426,1424,1,0,0,0,1426,1427,1,0,0,0,1427, - 1429,1,0,0,0,1428,1426,1,0,0,0,1429,1430,5,295,0,0,1430,221,1,0, - 0,0,1431,1432,5,294,0,0,1432,1435,3,186,93,0,1433,1434,5,270,0,0, - 1434,1436,3,186,93,0,1435,1433,1,0,0,0,1436,1437,1,0,0,0,1437,1435, - 1,0,0,0,1437,1438,1,0,0,0,1438,1439,1,0,0,0,1439,1440,5,295,0,0, - 1440,223,1,0,0,0,1441,1442,7,12,0,0,1442,1451,5,294,0,0,1443,1448, - 3,186,93,0,1444,1445,5,270,0,0,1445,1447,3,186,93,0,1446,1444,1, - 0,0,0,1447,1450,1,0,0,0,1448,1446,1,0,0,0,1448,1449,1,0,0,0,1449, - 1452,1,0,0,0,1450,1448,1,0,0,0,1451,1443,1,0,0,0,1451,1452,1,0,0, - 0,1452,1453,1,0,0,0,1453,1454,5,295,0,0,1454,225,1,0,0,0,1455,1456, - 5,195,0,0,1456,1457,5,294,0,0,1457,1464,3,186,93,0,1458,1459,5,270, - 0,0,1459,1462,3,186,93,0,1460,1461,5,270,0,0,1461,1463,3,186,93, - 0,1462,1460,1,0,0,0,1462,1463,1,0,0,0,1463,1465,1,0,0,0,1464,1458, - 1,0,0,0,1464,1465,1,0,0,0,1465,1466,1,0,0,0,1466,1467,5,295,0,0, - 1467,1482,1,0,0,0,1468,1469,5,195,0,0,1469,1470,5,294,0,0,1470,1477, - 3,186,93,0,1471,1472,5,95,0,0,1472,1475,3,186,93,0,1473,1474,5,92, - 0,0,1474,1476,3,186,93,0,1475,1473,1,0,0,0,1475,1476,1,0,0,0,1476, - 1478,1,0,0,0,1477,1471,1,0,0,0,1477,1478,1,0,0,0,1478,1479,1,0,0, - 0,1479,1480,5,295,0,0,1480,1482,1,0,0,0,1481,1455,1,0,0,0,1481,1468, - 1,0,0,0,1482,227,1,0,0,0,1483,1484,5,160,0,0,1484,1485,5,294,0,0, - 1485,1486,3,186,93,0,1486,1487,5,270,0,0,1487,1488,3,186,93,0,1488, - 1489,5,295,0,0,1489,1498,1,0,0,0,1490,1491,5,160,0,0,1491,1492,5, - 294,0,0,1492,1493,3,186,93,0,1493,1494,5,106,0,0,1494,1495,3,186, - 93,0,1495,1496,5,295,0,0,1496,1498,1,0,0,0,1497,1483,1,0,0,0,1497, - 1490,1,0,0,0,1498,229,1,0,0,0,1499,1500,5,156,0,0,1500,1501,5,294, - 0,0,1501,1502,3,186,93,0,1502,1503,5,270,0,0,1503,1504,3,186,93, - 0,1504,1505,5,270,0,0,1505,1508,3,186,93,0,1506,1507,5,270,0,0,1507, - 1509,3,186,93,0,1508,1506,1,0,0,0,1508,1509,1,0,0,0,1509,1510,1, - 0,0,0,1510,1511,5,295,0,0,1511,1526,1,0,0,0,1512,1513,5,156,0,0, - 1513,1514,5,294,0,0,1514,1515,3,186,93,0,1515,1516,5,159,0,0,1516, - 1517,3,186,93,0,1517,1518,5,95,0,0,1518,1521,3,186,93,0,1519,1520, - 5,92,0,0,1520,1522,3,186,93,0,1521,1519,1,0,0,0,1521,1522,1,0,0, - 0,1522,1523,1,0,0,0,1523,1524,5,295,0,0,1524,1526,1,0,0,0,1525,1499, - 1,0,0,0,1525,1512,1,0,0,0,1526,231,1,0,0,0,1527,1528,5,44,0,0,1528, - 1529,5,294,0,0,1529,1530,5,277,0,0,1530,1540,5,295,0,0,1531,1532, - 7,13,0,0,1532,1534,5,294,0,0,1533,1535,3,98,49,0,1534,1533,1,0,0, - 0,1534,1535,1,0,0,0,1535,1536,1,0,0,0,1536,1537,3,186,93,0,1537, - 1538,5,295,0,0,1538,1540,1,0,0,0,1539,1527,1,0,0,0,1539,1531,1,0, - 0,0,1540,233,1,0,0,0,1541,1542,7,14,0,0,1542,1543,5,294,0,0,1543, - 1550,3,186,93,0,1544,1545,5,270,0,0,1545,1548,3,186,93,0,1546,1547, - 5,270,0,0,1547,1549,3,186,93,0,1548,1546,1,0,0,0,1548,1549,1,0,0, - 0,1549,1551,1,0,0,0,1550,1544,1,0,0,0,1550,1551,1,0,0,0,1551,1552, - 1,0,0,0,1552,1553,5,295,0,0,1553,1554,3,114,57,0,1554,235,1,0,0, - 0,1555,1556,5,24,0,0,1556,1557,5,294,0,0,1557,1558,3,186,93,0,1558, - 1559,5,10,0,0,1559,1560,3,276,138,0,1560,1561,5,295,0,0,1561,237, - 1,0,0,0,1562,1563,5,235,0,0,1563,1564,5,294,0,0,1564,1565,3,186, - 93,0,1565,1566,5,10,0,0,1566,1567,3,276,138,0,1567,1568,5,295,0, - 0,1568,239,1,0,0,0,1569,1570,5,234,0,0,1570,1571,5,294,0,0,1571, - 1572,3,186,93,0,1572,1573,5,10,0,0,1573,1574,3,276,138,0,1574,1575, - 5,295,0,0,1575,241,1,0,0,0,1576,1577,5,85,0,0,1577,1578,5,294,0, - 0,1578,1579,5,303,0,0,1579,1580,5,95,0,0,1580,1581,3,186,93,0,1581, - 1582,5,295,0,0,1582,243,1,0,0,0,1583,1584,5,207,0,0,1584,1592,5, - 294,0,0,1585,1587,5,303,0,0,1586,1585,1,0,0,0,1586,1587,1,0,0,0, - 1587,1589,1,0,0,0,1588,1590,3,186,93,0,1589,1588,1,0,0,0,1589,1590, - 1,0,0,0,1590,1591,1,0,0,0,1591,1593,5,95,0,0,1592,1586,1,0,0,0,1592, - 1593,1,0,0,0,1593,1594,1,0,0,0,1594,1595,3,186,93,0,1595,1596,5, - 295,0,0,1596,245,1,0,0,0,1597,1598,7,15,0,0,1598,1599,5,294,0,0, - 1599,1600,5,303,0,0,1600,1601,5,270,0,0,1601,1602,3,186,93,0,1602, - 1603,5,270,0,0,1603,1604,3,186,93,0,1604,1605,5,295,0,0,1605,247, - 1,0,0,0,1606,1607,3,250,125,0,1607,1616,5,294,0,0,1608,1613,3,186, - 93,0,1609,1610,5,270,0,0,1610,1612,3,186,93,0,1611,1609,1,0,0,0, - 1612,1615,1,0,0,0,1613,1611,1,0,0,0,1613,1614,1,0,0,0,1614,1617, - 1,0,0,0,1615,1613,1,0,0,0,1616,1608,1,0,0,0,1616,1617,1,0,0,0,1617, - 1618,1,0,0,0,1618,1619,5,295,0,0,1619,249,1,0,0,0,1620,1621,3,12, - 6,0,1621,1622,5,299,0,0,1622,1624,1,0,0,0,1623,1620,1,0,0,0,1624, - 1627,1,0,0,0,1625,1623,1,0,0,0,1625,1626,1,0,0,0,1626,1628,1,0,0, - 0,1627,1625,1,0,0,0,1628,1639,7,16,0,0,1629,1630,3,12,6,0,1630,1631, - 5,299,0,0,1631,1633,1,0,0,0,1632,1629,1,0,0,0,1633,1636,1,0,0,0, - 1634,1632,1,0,0,0,1634,1635,1,0,0,0,1635,1637,1,0,0,0,1636,1634, - 1,0,0,0,1637,1639,3,12,6,0,1638,1625,1,0,0,0,1638,1634,1,0,0,0,1639, - 251,1,0,0,0,1640,1641,5,290,0,0,1641,1642,3,186,93,0,1642,1643,5, - 291,0,0,1643,1652,1,0,0,0,1644,1645,5,290,0,0,1645,1646,5,277,0, - 0,1646,1652,5,291,0,0,1647,1648,5,299,0,0,1648,1652,3,12,6,0,1649, - 1650,5,299,0,0,1650,1652,5,277,0,0,1651,1640,1,0,0,0,1651,1644,1, - 0,0,0,1651,1647,1,0,0,0,1651,1649,1,0,0,0,1652,253,1,0,0,0,1653, - 1654,5,294,0,0,1654,1655,3,208,104,0,1655,1656,5,130,0,0,1656,1657, - 3,138,69,0,1657,1658,5,295,0,0,1658,255,1,0,0,0,1659,1660,3,208, - 104,0,1660,1661,5,130,0,0,1661,1662,3,136,68,0,1662,257,1,0,0,0, - 1663,1664,5,298,0,0,1664,259,1,0,0,0,1665,1667,5,275,0,0,1666,1665, - 1,0,0,0,1666,1667,1,0,0,0,1667,1668,1,0,0,0,1668,1674,7,0,0,0,1669, - 1671,5,275,0,0,1670,1669,1,0,0,0,1670,1671,1,0,0,0,1671,1672,1,0, - 0,0,1672,1674,3,262,131,0,1673,1666,1,0,0,0,1673,1670,1,0,0,0,1674, - 261,1,0,0,0,1675,1676,5,79,0,0,1676,263,1,0,0,0,1677,1680,3,266, - 133,0,1678,1680,3,268,134,0,1679,1677,1,0,0,0,1679,1678,1,0,0,0, - 1680,265,1,0,0,0,1681,1690,5,290,0,0,1682,1687,3,186,93,0,1683,1684, - 5,270,0,0,1684,1686,3,186,93,0,1685,1683,1,0,0,0,1686,1689,1,0,0, - 0,1687,1685,1,0,0,0,1687,1688,1,0,0,0,1688,1691,1,0,0,0,1689,1687, - 1,0,0,0,1690,1682,1,0,0,0,1690,1691,1,0,0,0,1691,1692,1,0,0,0,1692, - 1693,5,291,0,0,1693,267,1,0,0,0,1694,1703,5,288,0,0,1695,1700,3, - 186,93,0,1696,1697,5,270,0,0,1697,1699,3,186,93,0,1698,1696,1,0, - 0,0,1699,1702,1,0,0,0,1700,1698,1,0,0,0,1700,1701,1,0,0,0,1701,1704, - 1,0,0,0,1702,1700,1,0,0,0,1703,1695,1,0,0,0,1703,1704,1,0,0,0,1704, - 1705,1,0,0,0,1705,1706,5,289,0,0,1706,269,1,0,0,0,1707,1716,5,292, - 0,0,1708,1713,3,272,136,0,1709,1710,5,270,0,0,1710,1712,3,272,136, - 0,1711,1709,1,0,0,0,1712,1715,1,0,0,0,1713,1711,1,0,0,0,1713,1714, - 1,0,0,0,1714,1717,1,0,0,0,1715,1713,1,0,0,0,1716,1708,1,0,0,0,1716, - 1717,1,0,0,0,1717,1718,1,0,0,0,1718,1719,5,293,0,0,1719,271,1,0, - 0,0,1720,1721,3,186,93,0,1721,1722,5,296,0,0,1722,1723,3,186,93, - 0,1723,273,1,0,0,0,1724,1759,5,141,0,0,1725,1759,5,236,0,0,1726, - 1759,5,208,0,0,1727,1759,5,88,0,0,1728,1759,5,300,0,0,1729,1759, - 5,301,0,0,1730,1759,5,302,0,0,1731,1759,5,309,0,0,1732,1733,5,53, - 0,0,1733,1759,5,300,0,0,1734,1738,5,201,0,0,1735,1736,5,294,0,0, - 1736,1737,5,301,0,0,1737,1739,5,295,0,0,1738,1735,1,0,0,0,1738,1739, - 1,0,0,0,1739,1743,1,0,0,0,1740,1741,5,226,0,0,1741,1742,5,201,0, - 0,1742,1744,5,229,0,0,1743,1740,1,0,0,0,1743,1744,1,0,0,0,1744,1745, - 1,0,0,0,1745,1759,5,300,0,0,1746,1750,5,202,0,0,1747,1748,5,294, - 0,0,1748,1749,5,301,0,0,1749,1751,5,295,0,0,1750,1747,1,0,0,0,1750, - 1751,1,0,0,0,1751,1755,1,0,0,0,1752,1753,5,226,0,0,1753,1754,5,201, - 0,0,1754,1756,5,229,0,0,1755,1752,1,0,0,0,1755,1756,1,0,0,0,1756, - 1757,1,0,0,0,1757,1759,5,300,0,0,1758,1724,1,0,0,0,1758,1725,1,0, - 0,0,1758,1726,1,0,0,0,1758,1727,1,0,0,0,1758,1728,1,0,0,0,1758,1729, - 1,0,0,0,1758,1730,1,0,0,0,1758,1731,1,0,0,0,1758,1732,1,0,0,0,1758, - 1734,1,0,0,0,1758,1746,1,0,0,0,1759,275,1,0,0,0,1760,1799,7,17,0, - 0,1761,1762,5,69,0,0,1762,1799,5,161,0,0,1763,1767,7,18,0,0,1764, - 1765,5,294,0,0,1765,1766,5,301,0,0,1766,1768,5,295,0,0,1767,1764, - 1,0,0,0,1767,1768,1,0,0,0,1768,1799,1,0,0,0,1769,1770,5,27,0,0,1770, - 1774,5,221,0,0,1771,1772,5,294,0,0,1772,1773,5,301,0,0,1773,1775, - 5,295,0,0,1774,1771,1,0,0,0,1774,1775,1,0,0,0,1775,1799,1,0,0,0, - 1776,1784,7,19,0,0,1777,1778,5,294,0,0,1778,1781,5,301,0,0,1779, - 1780,5,270,0,0,1780,1782,5,301,0,0,1781,1779,1,0,0,0,1781,1782,1, - 0,0,0,1782,1783,1,0,0,0,1783,1785,5,295,0,0,1784,1777,1,0,0,0,1784, - 1785,1,0,0,0,1785,1799,1,0,0,0,1786,1790,7,20,0,0,1787,1788,5,294, - 0,0,1788,1789,5,301,0,0,1789,1791,5,295,0,0,1790,1787,1,0,0,0,1790, - 1791,1,0,0,0,1791,1795,1,0,0,0,1792,1793,5,226,0,0,1793,1794,5,201, - 0,0,1794,1796,5,229,0,0,1795,1792,1,0,0,0,1795,1796,1,0,0,0,1796, - 1799,1,0,0,0,1797,1799,3,12,6,0,1798,1760,1,0,0,0,1798,1761,1,0, - 0,0,1798,1763,1,0,0,0,1798,1769,1,0,0,0,1798,1776,1,0,0,0,1798,1786, - 1,0,0,0,1798,1797,1,0,0,0,1799,277,1,0,0,0,226,285,290,292,299,303, - 307,311,313,338,341,348,363,372,384,389,400,407,415,420,427,433, - 436,439,443,448,451,456,464,470,483,489,497,511,514,517,523,527, - 532,543,546,561,569,581,586,591,602,612,615,623,632,637,640,643, - 649,656,661,666,675,682,687,690,700,714,719,723,727,735,739,748, - 753,756,767,777,789,796,811,826,831,838,842,845,850,856,862,867, - 869,878,882,885,891,895,897,901,904,909,912,916,920,923,928,931, - 935,937,944,947,983,987,991,994,1006,1017,1023,1031,1039,1043,1045, - 1053,1057,1067,1073,1075,1080,1087,1090,1093,1097,1100,1103,1105, - 1110,1113,1116,1123,1131,1135,1139,1142,1151,1155,1160,1164,1169, - 1173,1176,1178,1183,1187,1190,1193,1196,1199,1202,1205,1208,1218, - 1229,1235,1246,1251,1260,1266,1272,1276,1283,1285,1296,1307,1318, - 1324,1347,1353,1357,1371,1387,1394,1403,1407,1417,1426,1437,1448, - 1451,1462,1464,1475,1477,1481,1497,1508,1521,1525,1534,1539,1548, - 1550,1586,1589,1592,1613,1616,1625,1634,1638,1651,1666,1670,1673, - 1679,1687,1690,1700,1703,1713,1716,1738,1743,1750,1755,1758,1767, - 1774,1781,1784,1790,1795,1798 + 272,274,276,278,0,21,1,0,303,304,2,0,4,4,247,247,1,0,248,249,2,0, + 4,4,67,67,2,0,11,11,62,62,2,0,90,90,123,123,2,0,4,4,8,8,2,0,271, + 271,277,277,2,0,281,284,286,287,2,0,279,279,285,285,1,0,271,272, + 2,0,273,274,277,277,1,0,266,267,7,0,8,8,15,15,44,44,75,75,131,132, + 189,189,196,196,1,0,230,231,1,0,86,87,8,0,19,19,28,29,44,44,82,82, + 129,129,145,145,187,187,213,213,9,0,8,8,26,27,53,53,113,114,141, + 141,170,170,188,188,236,236,251,268,3,0,26,27,91,91,220,220,2,0, + 55,56,144,144,1,0,201,202,1991,0,294,1,0,0,0,2,315,1,0,0,0,4,317, + 1,0,0,0,6,320,1,0,0,0,8,323,1,0,0,0,10,326,1,0,0,0,12,329,1,0,0, + 0,14,331,1,0,0,0,16,333,1,0,0,0,18,350,1,0,0,0,20,355,1,0,0,0,22, + 357,1,0,0,0,24,359,1,0,0,0,26,361,1,0,0,0,28,365,1,0,0,0,30,391, + 1,0,0,0,32,402,1,0,0,0,34,404,1,0,0,0,36,412,1,0,0,0,38,422,1,0, + 0,0,40,429,1,0,0,0,42,458,1,0,0,0,44,466,1,0,0,0,46,468,1,0,0,0, + 48,485,1,0,0,0,50,487,1,0,0,0,52,495,1,0,0,0,54,503,1,0,0,0,56,506, + 1,0,0,0,58,541,1,0,0,0,60,543,1,0,0,0,62,554,1,0,0,0,64,561,1,0, + 0,0,66,573,1,0,0,0,68,594,1,0,0,0,70,596,1,0,0,0,72,606,1,0,0,0, + 74,608,1,0,0,0,76,613,1,0,0,0,78,618,1,0,0,0,80,621,1,0,0,0,82,630, + 1,0,0,0,84,634,1,0,0,0,86,642,1,0,0,0,88,657,1,0,0,0,90,674,1,0, + 0,0,92,676,1,0,0,0,94,700,1,0,0,0,96,702,1,0,0,0,98,710,1,0,0,0, + 100,717,1,0,0,0,102,719,1,0,0,0,104,728,1,0,0,0,106,732,1,0,0,0, + 108,742,1,0,0,0,110,750,1,0,0,0,112,766,1,0,0,0,114,770,1,0,0,0, + 116,775,1,0,0,0,118,785,1,0,0,0,120,795,1,0,0,0,122,805,1,0,0,0, + 124,808,1,0,0,0,126,817,1,0,0,0,128,836,1,0,0,0,130,838,1,0,0,0, + 132,841,1,0,0,0,134,844,1,0,0,0,136,847,1,0,0,0,138,851,1,0,0,0, + 140,856,1,0,0,0,142,867,1,0,0,0,144,881,1,0,0,0,146,894,1,0,0,0, + 148,896,1,0,0,0,150,899,1,0,0,0,152,901,1,0,0,0,154,922,1,0,0,0, + 156,962,1,0,0,0,158,972,1,0,0,0,160,1008,1,0,0,0,162,1010,1,0,0, + 0,164,1023,1,0,0,0,166,1034,1,0,0,0,168,1048,1,0,0,0,170,1056,1, + 0,0,0,172,1070,1,0,0,0,174,1078,1,0,0,0,176,1105,1,0,0,0,178,1130, + 1,0,0,0,180,1132,1,0,0,0,182,1148,1,0,0,0,184,1150,1,0,0,0,186,1167, + 1,0,0,0,188,1169,1,0,0,0,190,1171,1,0,0,0,192,1233,1,0,0,0,194,1235, + 1,0,0,0,196,1246,1,0,0,0,198,1260,1,0,0,0,200,1262,1,0,0,0,202,1313, + 1,0,0,0,204,1324,1,0,0,0,206,1335,1,0,0,0,208,1349,1,0,0,0,210,1372, + 1,0,0,0,212,1396,1,0,0,0,214,1398,1,0,0,0,216,1405,1,0,0,0,218,1417, + 1,0,0,0,220,1436,1,0,0,0,222,1445,1,0,0,0,224,1456,1,0,0,0,226,1466, + 1,0,0,0,228,1506,1,0,0,0,230,1522,1,0,0,0,232,1550,1,0,0,0,234,1564, + 1,0,0,0,236,1566,1,0,0,0,238,1580,1,0,0,0,240,1587,1,0,0,0,242,1594, + 1,0,0,0,244,1601,1,0,0,0,246,1608,1,0,0,0,248,1622,1,0,0,0,250,1631, + 1,0,0,0,252,1663,1,0,0,0,254,1676,1,0,0,0,256,1678,1,0,0,0,258,1684, + 1,0,0,0,260,1688,1,0,0,0,262,1698,1,0,0,0,264,1700,1,0,0,0,266,1704, + 1,0,0,0,268,1706,1,0,0,0,270,1719,1,0,0,0,272,1732,1,0,0,0,274,1745, + 1,0,0,0,276,1783,1,0,0,0,278,1823,1,0,0,0,280,292,5,83,0,0,281,282, + 5,294,0,0,282,287,3,4,2,0,283,284,5,270,0,0,284,286,3,4,2,0,285, + 283,1,0,0,0,286,289,1,0,0,0,287,285,1,0,0,0,287,288,1,0,0,0,288, + 290,1,0,0,0,289,287,1,0,0,0,290,291,5,295,0,0,291,293,1,0,0,0,292, + 281,1,0,0,0,292,293,1,0,0,0,293,295,1,0,0,0,294,280,1,0,0,0,294, + 295,1,0,0,0,295,296,1,0,0,0,296,297,3,2,1,0,297,298,5,0,0,1,298, + 1,1,0,0,0,299,301,3,14,7,0,300,302,5,297,0,0,301,300,1,0,0,0,301, + 302,1,0,0,0,302,316,1,0,0,0,303,305,3,42,21,0,304,306,5,297,0,0, + 305,304,1,0,0,0,305,306,1,0,0,0,306,316,1,0,0,0,307,309,3,28,14, + 0,308,310,5,297,0,0,309,308,1,0,0,0,309,310,1,0,0,0,310,316,1,0, + 0,0,311,313,3,16,8,0,312,314,5,297,0,0,313,312,1,0,0,0,313,314,1, + 0,0,0,314,316,1,0,0,0,315,299,1,0,0,0,315,303,1,0,0,0,315,307,1, + 0,0,0,315,311,1,0,0,0,316,3,1,0,0,0,317,318,5,303,0,0,318,319,5, + 303,0,0,319,5,1,0,0,0,320,321,5,10,0,0,321,322,3,12,6,0,322,7,1, + 0,0,0,323,324,5,13,0,0,324,325,3,12,6,0,325,9,1,0,0,0,326,327,5, + 20,0,0,327,328,3,12,6,0,328,11,1,0,0,0,329,330,7,0,0,0,330,13,1, + 0,0,0,331,332,3,188,94,0,332,15,1,0,0,0,333,334,5,80,0,0,334,343, + 3,188,94,0,335,340,3,188,94,0,336,337,5,270,0,0,337,339,3,188,94, + 0,338,336,1,0,0,0,339,342,1,0,0,0,340,338,1,0,0,0,340,341,1,0,0, + 0,341,344,1,0,0,0,342,340,1,0,0,0,343,335,1,0,0,0,343,344,1,0,0, + 0,344,17,1,0,0,0,345,346,3,12,6,0,346,347,5,299,0,0,347,349,1,0, + 0,0,348,345,1,0,0,0,349,352,1,0,0,0,350,348,1,0,0,0,350,351,1,0, + 0,0,351,353,1,0,0,0,352,350,1,0,0,0,353,354,3,12,6,0,354,19,1,0, + 0,0,355,356,3,12,6,0,356,21,1,0,0,0,357,358,3,12,6,0,358,23,1,0, + 0,0,359,360,3,12,6,0,360,25,1,0,0,0,361,362,3,12,6,0,362,27,1,0, + 0,0,363,366,3,30,15,0,364,366,3,32,16,0,365,363,1,0,0,0,365,364, + 1,0,0,0,366,29,1,0,0,0,367,368,5,45,0,0,368,369,5,198,0,0,369,374, + 3,18,9,0,370,371,5,294,0,0,371,372,3,34,17,0,372,373,5,295,0,0,373, + 375,1,0,0,0,374,370,1,0,0,0,374,375,1,0,0,0,375,392,1,0,0,0,376, + 377,5,45,0,0,377,378,5,242,0,0,378,379,5,147,0,0,379,380,3,12,6, + 0,380,381,5,294,0,0,381,386,3,46,23,0,382,383,5,270,0,0,383,385, + 3,46,23,0,384,382,1,0,0,0,385,388,1,0,0,0,386,384,1,0,0,0,386,387, + 1,0,0,0,387,389,1,0,0,0,388,386,1,0,0,0,389,390,5,295,0,0,390,392, + 1,0,0,0,391,367,1,0,0,0,391,376,1,0,0,0,392,31,1,0,0,0,393,394,5, + 70,0,0,394,395,5,198,0,0,395,403,3,18,9,0,396,397,5,70,0,0,397,398, + 5,242,0,0,398,399,3,12,6,0,399,400,5,147,0,0,400,401,3,12,6,0,401, + 403,1,0,0,0,402,393,1,0,0,0,402,396,1,0,0,0,403,33,1,0,0,0,404,409, + 3,36,18,0,405,406,5,270,0,0,406,408,3,36,18,0,407,405,1,0,0,0,408, + 411,1,0,0,0,409,407,1,0,0,0,409,410,1,0,0,0,410,35,1,0,0,0,411,409, + 1,0,0,0,412,413,3,24,12,0,413,417,3,278,139,0,414,416,3,38,19,0, + 415,414,1,0,0,0,416,419,1,0,0,0,417,415,1,0,0,0,417,418,1,0,0,0, + 418,37,1,0,0,0,419,417,1,0,0,0,420,421,5,39,0,0,421,423,3,26,13, + 0,422,420,1,0,0,0,422,423,1,0,0,0,423,424,1,0,0,0,424,425,3,40,20, + 0,425,39,1,0,0,0,426,427,5,140,0,0,427,430,5,141,0,0,428,430,5,141, + 0,0,429,426,1,0,0,0,429,428,1,0,0,0,430,41,1,0,0,0,431,433,3,78, + 39,0,432,434,3,44,22,0,433,432,1,0,0,0,434,435,1,0,0,0,435,433,1, + 0,0,0,435,436,1,0,0,0,436,438,1,0,0,0,437,439,3,92,46,0,438,437, + 1,0,0,0,438,439,1,0,0,0,439,441,1,0,0,0,440,442,3,86,43,0,441,440, + 1,0,0,0,441,442,1,0,0,0,442,459,1,0,0,0,443,445,3,130,65,0,444,446, + 3,92,46,0,445,444,1,0,0,0,445,446,1,0,0,0,446,448,1,0,0,0,447,449, + 3,44,22,0,448,447,1,0,0,0,449,450,1,0,0,0,450,448,1,0,0,0,450,451, + 1,0,0,0,451,453,1,0,0,0,452,454,3,86,43,0,453,452,1,0,0,0,453,454, + 1,0,0,0,454,459,1,0,0,0,455,459,3,84,42,0,456,459,3,56,28,0,457, + 459,3,44,22,0,458,431,1,0,0,0,458,443,1,0,0,0,458,455,1,0,0,0,458, + 456,1,0,0,0,458,457,1,0,0,0,459,43,1,0,0,0,460,467,3,58,29,0,461, + 467,3,64,32,0,462,467,3,80,40,0,463,467,3,50,25,0,464,467,3,54,27, + 0,465,467,3,52,26,0,466,460,1,0,0,0,466,461,1,0,0,0,466,462,1,0, + 0,0,466,463,1,0,0,0,466,464,1,0,0,0,466,465,1,0,0,0,467,45,1,0,0, + 0,468,472,3,12,6,0,469,471,3,48,24,0,470,469,1,0,0,0,471,474,1,0, + 0,0,472,470,1,0,0,0,472,473,1,0,0,0,473,47,1,0,0,0,474,472,1,0,0, + 0,475,476,5,290,0,0,476,477,3,276,138,0,477,478,5,291,0,0,478,486, + 1,0,0,0,479,480,5,290,0,0,480,481,3,12,6,0,481,482,5,291,0,0,482, + 486,1,0,0,0,483,484,5,299,0,0,484,486,3,12,6,0,485,475,1,0,0,0,485, + 479,1,0,0,0,485,483,1,0,0,0,486,49,1,0,0,0,487,488,5,173,0,0,488, + 489,5,117,0,0,489,491,3,12,6,0,490,492,3,6,3,0,491,490,1,0,0,0,491, + 492,1,0,0,0,492,493,1,0,0,0,493,494,3,188,94,0,494,51,1,0,0,0,495, + 496,5,214,0,0,496,497,5,117,0,0,497,499,3,12,6,0,498,500,3,6,3,0, + 499,498,1,0,0,0,499,500,1,0,0,0,500,501,1,0,0,0,501,502,3,188,94, + 0,502,53,1,0,0,0,503,504,5,241,0,0,504,505,3,46,23,0,505,55,1,0, + 0,0,506,507,5,112,0,0,507,508,5,117,0,0,508,509,3,46,23,0,509,510, + 5,218,0,0,510,513,3,188,94,0,511,512,5,13,0,0,512,514,3,188,94,0, + 513,511,1,0,0,0,513,514,1,0,0,0,514,516,1,0,0,0,515,517,3,66,33, + 0,516,515,1,0,0,0,516,517,1,0,0,0,517,519,1,0,0,0,518,520,3,86,43, + 0,519,518,1,0,0,0,519,520,1,0,0,0,520,57,1,0,0,0,521,522,5,112,0, + 0,522,523,5,117,0,0,523,525,3,12,6,0,524,526,3,6,3,0,525,524,1,0, + 0,0,525,526,1,0,0,0,526,527,1,0,0,0,527,529,3,188,94,0,528,530,3, + 62,31,0,529,528,1,0,0,0,529,530,1,0,0,0,530,542,1,0,0,0,531,532, + 5,112,0,0,532,533,5,117,0,0,533,535,3,12,6,0,534,536,3,60,30,0,535, + 534,1,0,0,0,535,536,1,0,0,0,536,537,1,0,0,0,537,539,3,220,110,0, + 538,540,3,62,31,0,539,538,1,0,0,0,539,540,1,0,0,0,540,542,1,0,0, + 0,541,521,1,0,0,0,541,531,1,0,0,0,542,59,1,0,0,0,543,544,5,294,0, + 0,544,549,3,24,12,0,545,546,5,270,0,0,546,548,3,24,12,0,547,545, + 1,0,0,0,548,551,1,0,0,0,549,547,1,0,0,0,549,550,1,0,0,0,550,552, + 1,0,0,0,551,549,1,0,0,0,552,553,5,295,0,0,553,61,1,0,0,0,554,555, + 5,147,0,0,555,557,5,244,0,0,556,558,3,68,34,0,557,556,1,0,0,0,557, + 558,1,0,0,0,558,559,1,0,0,0,559,560,3,72,36,0,560,63,1,0,0,0,561, + 562,5,112,0,0,562,563,5,117,0,0,563,564,3,46,23,0,564,565,5,218, + 0,0,565,568,3,188,94,0,566,567,5,13,0,0,567,569,3,188,94,0,568,566, + 1,0,0,0,568,569,1,0,0,0,569,571,1,0,0,0,570,572,3,66,33,0,571,570, + 1,0,0,0,571,572,1,0,0,0,572,65,1,0,0,0,573,574,5,147,0,0,574,575, + 5,244,0,0,575,576,5,225,0,0,576,577,3,188,94,0,577,578,5,245,0,0, + 578,579,5,250,0,0,579,67,1,0,0,0,580,581,5,294,0,0,581,586,3,12, + 6,0,582,583,5,270,0,0,583,585,3,12,6,0,584,582,1,0,0,0,585,588,1, + 0,0,0,586,584,1,0,0,0,586,587,1,0,0,0,587,589,1,0,0,0,588,586,1, + 0,0,0,589,590,5,295,0,0,590,595,1,0,0,0,591,592,5,147,0,0,592,593, + 5,39,0,0,593,595,3,70,35,0,594,580,1,0,0,0,594,591,1,0,0,0,595,69, + 1,0,0,0,596,597,3,12,6,0,597,71,1,0,0,0,598,599,5,245,0,0,599,607, + 5,250,0,0,600,601,5,245,0,0,601,602,5,173,0,0,602,607,3,74,37,0, + 603,604,5,245,0,0,604,605,5,212,0,0,605,607,3,76,38,0,606,598,1, + 0,0,0,606,600,1,0,0,0,606,603,1,0,0,0,607,73,1,0,0,0,608,611,5,79, + 0,0,609,610,5,225,0,0,610,612,3,188,94,0,611,609,1,0,0,0,611,612, + 1,0,0,0,612,75,1,0,0,0,613,616,5,79,0,0,614,615,5,225,0,0,615,617, + 3,188,94,0,616,614,1,0,0,0,616,617,1,0,0,0,617,77,1,0,0,0,618,619, + 5,212,0,0,619,620,3,178,89,0,620,79,1,0,0,0,621,622,5,185,0,0,622, + 627,3,82,41,0,623,624,5,270,0,0,624,626,3,82,41,0,625,623,1,0,0, + 0,626,629,1,0,0,0,627,625,1,0,0,0,627,628,1,0,0,0,628,81,1,0,0,0, + 629,627,1,0,0,0,630,631,3,46,23,0,631,632,5,283,0,0,632,633,3,188, + 94,0,633,83,1,0,0,0,634,635,5,61,0,0,635,637,3,90,45,0,636,638,3, + 92,46,0,637,636,1,0,0,0,637,638,1,0,0,0,638,640,1,0,0,0,639,641, + 3,86,43,0,640,639,1,0,0,0,640,641,1,0,0,0,641,85,1,0,0,0,642,643, + 5,246,0,0,643,648,3,88,44,0,644,645,5,270,0,0,645,647,3,88,44,0, + 646,644,1,0,0,0,647,650,1,0,0,0,648,646,1,0,0,0,648,649,1,0,0,0, + 649,87,1,0,0,0,650,648,1,0,0,0,651,652,7,1,0,0,652,653,7,2,0,0,653, + 658,5,277,0,0,654,655,7,1,0,0,655,656,7,2,0,0,656,658,3,188,94,0, + 657,651,1,0,0,0,657,654,1,0,0,0,658,89,1,0,0,0,659,660,5,95,0,0, + 660,662,3,46,23,0,661,663,3,6,3,0,662,661,1,0,0,0,662,663,1,0,0, + 0,663,665,1,0,0,0,664,666,3,8,4,0,665,664,1,0,0,0,665,666,1,0,0, + 0,666,668,1,0,0,0,667,669,3,10,5,0,668,667,1,0,0,0,668,669,1,0,0, + 0,669,675,1,0,0,0,670,671,5,95,0,0,671,672,3,46,23,0,672,673,3,12, + 6,0,673,675,1,0,0,0,674,659,1,0,0,0,674,670,1,0,0,0,675,91,1,0,0, + 0,676,677,5,225,0,0,677,678,3,188,94,0,678,93,1,0,0,0,679,681,5, + 182,0,0,680,682,3,100,50,0,681,680,1,0,0,0,681,682,1,0,0,0,682,683, + 1,0,0,0,683,701,5,277,0,0,684,686,5,182,0,0,685,687,3,100,50,0,686, + 685,1,0,0,0,686,687,1,0,0,0,687,688,1,0,0,0,688,701,3,96,48,0,689, + 691,5,182,0,0,690,692,3,100,50,0,691,690,1,0,0,0,691,692,1,0,0,0, + 692,693,1,0,0,0,693,694,5,218,0,0,694,701,3,188,94,0,695,696,5,237, + 0,0,696,697,3,188,94,0,697,698,5,13,0,0,698,699,3,188,94,0,699,701, + 1,0,0,0,700,679,1,0,0,0,700,684,1,0,0,0,700,689,1,0,0,0,700,695, + 1,0,0,0,701,95,1,0,0,0,702,707,3,98,49,0,703,704,5,270,0,0,704,706, + 3,98,49,0,705,703,1,0,0,0,706,709,1,0,0,0,707,705,1,0,0,0,707,708, + 1,0,0,0,708,97,1,0,0,0,709,707,1,0,0,0,710,715,3,188,94,0,711,713, + 5,10,0,0,712,711,1,0,0,0,712,713,1,0,0,0,713,714,1,0,0,0,714,716, + 3,12,6,0,715,712,1,0,0,0,715,716,1,0,0,0,716,99,1,0,0,0,717,718, + 7,3,0,0,718,101,1,0,0,0,719,720,5,243,0,0,720,725,3,104,52,0,721, + 722,5,270,0,0,722,724,3,104,52,0,723,721,1,0,0,0,724,727,1,0,0,0, + 725,723,1,0,0,0,725,726,1,0,0,0,726,103,1,0,0,0,727,725,1,0,0,0, + 728,729,3,188,94,0,729,730,5,10,0,0,730,731,3,12,6,0,731,105,1,0, + 0,0,732,733,5,152,0,0,733,734,5,20,0,0,734,739,3,108,54,0,735,736, + 5,270,0,0,736,738,3,108,54,0,737,735,1,0,0,0,738,741,1,0,0,0,739, + 737,1,0,0,0,739,740,1,0,0,0,740,107,1,0,0,0,741,739,1,0,0,0,742, + 744,3,188,94,0,743,745,7,4,0,0,744,743,1,0,0,0,744,745,1,0,0,0,745, + 748,1,0,0,0,746,747,5,142,0,0,747,749,7,5,0,0,748,746,1,0,0,0,748, + 749,1,0,0,0,749,109,1,0,0,0,750,752,5,102,0,0,751,753,5,158,0,0, + 752,751,1,0,0,0,752,753,1,0,0,0,753,754,1,0,0,0,754,755,5,20,0,0, + 755,760,3,114,57,0,756,757,5,270,0,0,757,759,3,114,57,0,758,756, + 1,0,0,0,759,762,1,0,0,0,760,758,1,0,0,0,760,761,1,0,0,0,761,764, + 1,0,0,0,762,760,1,0,0,0,763,765,3,112,56,0,764,763,1,0,0,0,764,765, + 1,0,0,0,765,111,1,0,0,0,766,767,5,102,0,0,767,768,5,10,0,0,768,769, + 3,12,6,0,769,113,1,0,0,0,770,773,3,192,96,0,771,772,5,10,0,0,772, + 774,3,12,6,0,773,771,1,0,0,0,773,774,1,0,0,0,774,115,1,0,0,0,775, + 776,5,232,0,0,776,778,5,294,0,0,777,779,3,118,59,0,778,777,1,0,0, + 0,778,779,1,0,0,0,779,781,1,0,0,0,780,782,3,120,60,0,781,780,1,0, + 0,0,781,782,1,0,0,0,782,783,1,0,0,0,783,784,5,295,0,0,784,117,1, + 0,0,0,785,786,5,233,0,0,786,787,5,20,0,0,787,792,3,188,94,0,788, + 789,5,270,0,0,789,791,3,188,94,0,790,788,1,0,0,0,791,794,1,0,0,0, + 792,790,1,0,0,0,792,793,1,0,0,0,793,119,1,0,0,0,794,792,1,0,0,0, + 795,796,5,152,0,0,796,797,5,20,0,0,797,802,3,108,54,0,798,799,5, + 270,0,0,799,801,3,108,54,0,800,798,1,0,0,0,801,804,1,0,0,0,802,800, + 1,0,0,0,802,803,1,0,0,0,803,121,1,0,0,0,804,802,1,0,0,0,805,806, + 5,103,0,0,806,807,3,192,96,0,807,123,1,0,0,0,808,809,5,78,0,0,809, + 814,3,126,63,0,810,811,5,270,0,0,811,813,3,126,63,0,812,810,1,0, + 0,0,813,816,1,0,0,0,814,812,1,0,0,0,814,815,1,0,0,0,815,125,1,0, + 0,0,816,814,1,0,0,0,817,819,3,12,6,0,818,820,3,128,64,0,819,818, + 1,0,0,0,820,821,1,0,0,0,821,819,1,0,0,0,821,822,1,0,0,0,822,127, + 1,0,0,0,823,824,5,299,0,0,824,837,3,12,6,0,825,826,5,290,0,0,826, + 827,5,300,0,0,827,837,5,291,0,0,828,829,5,290,0,0,829,830,5,301, + 0,0,830,837,5,291,0,0,831,832,5,290,0,0,832,833,5,277,0,0,833,837, + 5,291,0,0,834,835,5,299,0,0,835,837,5,277,0,0,836,823,1,0,0,0,836, + 825,1,0,0,0,836,828,1,0,0,0,836,831,1,0,0,0,836,834,1,0,0,0,837, + 129,1,0,0,0,838,839,5,95,0,0,839,840,3,174,87,0,840,131,1,0,0,0, + 841,842,5,225,0,0,842,843,3,192,96,0,843,133,1,0,0,0,844,845,5,240, + 0,0,845,846,3,192,96,0,846,135,1,0,0,0,847,848,5,239,0,0,848,849, + 3,192,96,0,849,137,1,0,0,0,850,852,3,146,73,0,851,850,1,0,0,0,851, + 852,1,0,0,0,852,853,1,0,0,0,853,854,3,142,71,0,854,139,1,0,0,0,855, + 857,3,146,73,0,856,855,1,0,0,0,856,857,1,0,0,0,857,858,1,0,0,0,858, + 863,3,142,71,0,859,860,5,270,0,0,860,862,3,142,71,0,861,859,1,0, + 0,0,862,865,1,0,0,0,863,861,1,0,0,0,863,864,1,0,0,0,864,141,1,0, + 0,0,865,863,1,0,0,0,866,868,3,150,75,0,867,866,1,0,0,0,867,868,1, + 0,0,0,868,870,1,0,0,0,869,871,3,148,74,0,870,869,1,0,0,0,870,871, + 1,0,0,0,871,875,1,0,0,0,872,874,3,144,72,0,873,872,1,0,0,0,874,877, + 1,0,0,0,875,873,1,0,0,0,875,876,1,0,0,0,876,143,1,0,0,0,877,875, + 1,0,0,0,878,882,3,152,76,0,879,882,3,154,77,0,880,882,3,156,78,0, + 881,878,1,0,0,0,881,879,1,0,0,0,881,880,1,0,0,0,882,145,1,0,0,0, + 883,884,7,6,0,0,884,895,5,186,0,0,885,887,5,8,0,0,886,888,5,301, + 0,0,887,886,1,0,0,0,887,888,1,0,0,0,888,895,1,0,0,0,889,890,5,186, + 0,0,890,892,5,301,0,0,891,893,5,102,0,0,892,891,1,0,0,0,892,893, + 1,0,0,0,893,895,1,0,0,0,894,883,1,0,0,0,894,885,1,0,0,0,894,889, + 1,0,0,0,895,147,1,0,0,0,896,897,3,12,6,0,897,898,5,283,0,0,898,149, + 1,0,0,0,899,900,5,303,0,0,900,151,1,0,0,0,901,903,5,294,0,0,902, + 904,3,12,6,0,903,902,1,0,0,0,903,904,1,0,0,0,904,907,1,0,0,0,905, + 906,5,296,0,0,906,908,3,164,82,0,907,905,1,0,0,0,907,908,1,0,0,0, + 908,910,1,0,0,0,909,911,3,92,46,0,910,909,1,0,0,0,910,911,1,0,0, + 0,911,912,1,0,0,0,912,913,5,295,0,0,913,153,1,0,0,0,914,916,3,160, + 80,0,915,917,3,158,79,0,916,915,1,0,0,0,916,917,1,0,0,0,917,923, + 1,0,0,0,918,920,3,172,86,0,919,921,3,158,79,0,920,919,1,0,0,0,920, + 921,1,0,0,0,921,923,1,0,0,0,922,914,1,0,0,0,922,918,1,0,0,0,923, + 155,1,0,0,0,924,926,5,294,0,0,925,927,3,150,75,0,926,925,1,0,0,0, + 926,927,1,0,0,0,927,929,1,0,0,0,928,930,3,148,74,0,929,928,1,0,0, + 0,929,930,1,0,0,0,930,932,1,0,0,0,931,933,3,144,72,0,932,931,1,0, + 0,0,933,934,1,0,0,0,934,932,1,0,0,0,934,935,1,0,0,0,935,937,1,0, + 0,0,936,938,3,92,46,0,937,936,1,0,0,0,937,938,1,0,0,0,938,939,1, + 0,0,0,939,941,5,295,0,0,940,942,3,158,79,0,941,940,1,0,0,0,941,942, + 1,0,0,0,942,963,1,0,0,0,943,945,5,290,0,0,944,946,3,150,75,0,945, + 944,1,0,0,0,945,946,1,0,0,0,946,948,1,0,0,0,947,949,3,148,74,0,948, + 947,1,0,0,0,948,949,1,0,0,0,949,951,1,0,0,0,950,952,3,144,72,0,951, + 950,1,0,0,0,952,953,1,0,0,0,953,951,1,0,0,0,953,954,1,0,0,0,954, + 956,1,0,0,0,955,957,3,92,46,0,956,955,1,0,0,0,956,957,1,0,0,0,957, + 958,1,0,0,0,958,960,5,291,0,0,959,961,3,158,79,0,960,959,1,0,0,0, + 960,961,1,0,0,0,961,963,1,0,0,0,962,924,1,0,0,0,962,943,1,0,0,0, + 963,157,1,0,0,0,964,973,7,7,0,0,965,966,5,292,0,0,966,967,5,301, + 0,0,967,969,5,270,0,0,968,970,5,301,0,0,969,968,1,0,0,0,969,970, + 1,0,0,0,970,971,1,0,0,0,971,973,5,293,0,0,972,964,1,0,0,0,972,965, + 1,0,0,0,973,159,1,0,0,0,974,975,5,272,0,0,975,976,3,162,81,0,976, + 977,5,272,0,0,977,978,5,287,0,0,978,1009,1,0,0,0,979,980,5,276,0, + 0,980,981,3,162,81,0,981,982,5,276,0,0,982,1009,1,0,0,0,983,984, + 5,286,0,0,984,985,5,272,0,0,985,986,3,162,81,0,986,987,5,272,0,0, + 987,1009,1,0,0,0,988,989,5,276,0,0,989,990,3,162,81,0,990,991,5, + 276,0,0,991,992,5,287,0,0,992,1009,1,0,0,0,993,994,5,286,0,0,994, + 995,5,276,0,0,995,996,3,162,81,0,996,997,5,276,0,0,997,1009,1,0, + 0,0,998,999,5,286,0,0,999,1000,5,272,0,0,1000,1001,3,162,81,0,1001, + 1002,5,272,0,0,1002,1003,5,287,0,0,1003,1009,1,0,0,0,1004,1005,5, + 272,0,0,1005,1006,3,162,81,0,1006,1007,5,272,0,0,1007,1009,1,0,0, + 0,1008,974,1,0,0,0,1008,979,1,0,0,0,1008,983,1,0,0,0,1008,988,1, + 0,0,0,1008,993,1,0,0,0,1008,998,1,0,0,0,1008,1004,1,0,0,0,1009,161, + 1,0,0,0,1010,1012,5,290,0,0,1011,1013,3,12,6,0,1012,1011,1,0,0,0, + 1012,1013,1,0,0,0,1013,1016,1,0,0,0,1014,1015,5,296,0,0,1015,1017, + 3,164,82,0,1016,1014,1,0,0,0,1016,1017,1,0,0,0,1017,1019,1,0,0,0, + 1018,1020,3,92,46,0,1019,1018,1,0,0,0,1019,1020,1,0,0,0,1020,1021, + 1,0,0,0,1021,1022,5,291,0,0,1022,163,1,0,0,0,1023,1024,6,82,-1,0, + 1024,1025,3,166,83,0,1025,1031,1,0,0,0,1026,1027,10,2,0,0,1027,1028, + 5,278,0,0,1028,1030,3,166,83,0,1029,1026,1,0,0,0,1030,1033,1,0,0, + 0,1031,1029,1,0,0,0,1031,1032,1,0,0,0,1032,165,1,0,0,0,1033,1031, + 1,0,0,0,1034,1035,6,83,-1,0,1035,1036,3,168,84,0,1036,1042,1,0,0, + 0,1037,1038,10,2,0,0,1038,1039,5,279,0,0,1039,1041,3,168,84,0,1040, + 1037,1,0,0,0,1041,1044,1,0,0,0,1042,1040,1,0,0,0,1042,1043,1,0,0, + 0,1043,167,1,0,0,0,1044,1042,1,0,0,0,1045,1046,5,280,0,0,1046,1049, + 3,170,85,0,1047,1049,3,170,85,0,1048,1045,1,0,0,0,1048,1047,1,0, + 0,0,1049,169,1,0,0,0,1050,1057,3,12,6,0,1051,1057,5,274,0,0,1052, + 1053,5,294,0,0,1053,1054,3,164,82,0,1054,1055,5,295,0,0,1055,1057, + 1,0,0,0,1056,1050,1,0,0,0,1056,1051,1,0,0,0,1056,1052,1,0,0,0,1057, + 171,1,0,0,0,1058,1071,5,276,0,0,1059,1060,5,276,0,0,1060,1071,5, + 287,0,0,1061,1062,5,286,0,0,1062,1071,5,276,0,0,1063,1065,5,286, + 0,0,1064,1063,1,0,0,0,1064,1065,1,0,0,0,1065,1066,1,0,0,0,1066,1068, + 5,272,0,0,1067,1069,5,287,0,0,1068,1067,1,0,0,0,1068,1069,1,0,0, + 0,1069,1071,1,0,0,0,1070,1058,1,0,0,0,1070,1059,1,0,0,0,1070,1061, + 1,0,0,0,1070,1064,1,0,0,0,1071,173,1,0,0,0,1072,1073,6,87,-1,0,1073, + 1079,3,176,88,0,1074,1075,5,294,0,0,1075,1076,3,174,87,0,1076,1077, + 5,295,0,0,1077,1079,1,0,0,0,1078,1072,1,0,0,0,1078,1074,1,0,0,0, + 1079,1100,1,0,0,0,1080,1082,10,5,0,0,1081,1083,3,186,93,0,1082,1081, + 1,0,0,0,1082,1083,1,0,0,0,1083,1084,1,0,0,0,1084,1085,5,46,0,0,1085, + 1086,5,120,0,0,1086,1099,3,182,91,0,1087,1088,10,4,0,0,1088,1089, + 5,270,0,0,1089,1099,3,182,91,0,1090,1092,10,3,0,0,1091,1093,3,186, + 93,0,1092,1091,1,0,0,0,1092,1093,1,0,0,0,1093,1094,1,0,0,0,1094, + 1095,5,120,0,0,1095,1096,3,182,91,0,1096,1097,3,184,92,0,1097,1099, + 1,0,0,0,1098,1080,1,0,0,0,1098,1087,1,0,0,0,1098,1090,1,0,0,0,1099, + 1102,1,0,0,0,1100,1098,1,0,0,0,1100,1101,1,0,0,0,1101,175,1,0,0, + 0,1102,1100,1,0,0,0,1103,1106,3,178,89,0,1104,1106,3,180,90,0,1105, + 1103,1,0,0,0,1105,1104,1,0,0,0,1106,177,1,0,0,0,1107,1108,3,192, + 96,0,1108,1109,3,12,6,0,1109,1131,1,0,0,0,1110,1112,3,192,96,0,1111, + 1113,3,6,3,0,1112,1111,1,0,0,0,1112,1113,1,0,0,0,1113,1115,1,0,0, + 0,1114,1116,3,8,4,0,1115,1114,1,0,0,0,1115,1116,1,0,0,0,1116,1118, + 1,0,0,0,1117,1119,3,10,5,0,1118,1117,1,0,0,0,1118,1119,1,0,0,0,1119, + 1131,1,0,0,0,1120,1122,3,258,129,0,1121,1123,3,6,3,0,1122,1121,1, + 0,0,0,1122,1123,1,0,0,0,1123,1125,1,0,0,0,1124,1126,3,8,4,0,1125, + 1124,1,0,0,0,1125,1126,1,0,0,0,1126,1128,1,0,0,0,1127,1129,3,10, + 5,0,1128,1127,1,0,0,0,1128,1129,1,0,0,0,1129,1131,1,0,0,0,1130,1107, + 1,0,0,0,1130,1110,1,0,0,0,1130,1120,1,0,0,0,1131,179,1,0,0,0,1132, + 1133,5,238,0,0,1133,1135,3,188,94,0,1134,1136,3,6,3,0,1135,1134, + 1,0,0,0,1135,1136,1,0,0,0,1136,1138,1,0,0,0,1137,1139,3,8,4,0,1138, + 1137,1,0,0,0,1138,1139,1,0,0,0,1139,1141,1,0,0,0,1140,1142,3,10, + 5,0,1141,1140,1,0,0,0,1141,1142,1,0,0,0,1142,181,1,0,0,0,1143,1149, + 3,176,88,0,1144,1145,5,294,0,0,1145,1146,3,174,87,0,1146,1147,5, + 295,0,0,1147,1149,1,0,0,0,1148,1143,1,0,0,0,1148,1144,1,0,0,0,1149, + 183,1,0,0,0,1150,1151,5,147,0,0,1151,1152,3,188,94,0,1152,185,1, + 0,0,0,1153,1168,5,109,0,0,1154,1156,5,125,0,0,1155,1157,5,153,0, + 0,1156,1155,1,0,0,0,1156,1157,1,0,0,0,1157,1168,1,0,0,0,1158,1160, + 5,176,0,0,1159,1161,5,153,0,0,1160,1159,1,0,0,0,1160,1161,1,0,0, + 0,1161,1168,1,0,0,0,1162,1164,5,96,0,0,1163,1165,5,153,0,0,1164, + 1163,1,0,0,0,1164,1165,1,0,0,0,1165,1168,1,0,0,0,1166,1168,5,153, + 0,0,1167,1153,1,0,0,0,1167,1154,1,0,0,0,1167,1158,1,0,0,0,1167,1162, + 1,0,0,0,1167,1166,1,0,0,0,1168,187,1,0,0,0,1169,1170,3,190,95,0, + 1170,189,1,0,0,0,1171,1172,6,95,-1,0,1172,1173,3,192,96,0,1173,1203, + 1,0,0,0,1174,1176,10,4,0,0,1175,1177,5,153,0,0,1176,1175,1,0,0,0, + 1176,1177,1,0,0,0,1177,1178,1,0,0,0,1178,1180,5,76,0,0,1179,1181, + 7,3,0,0,1180,1179,1,0,0,0,1180,1181,1,0,0,0,1181,1182,1,0,0,0,1182, + 1202,3,192,96,0,1183,1185,10,3,0,0,1184,1186,5,153,0,0,1185,1184, + 1,0,0,0,1185,1186,1,0,0,0,1186,1187,1,0,0,0,1187,1189,5,209,0,0, + 1188,1190,7,3,0,0,1189,1188,1,0,0,0,1189,1190,1,0,0,0,1190,1191, + 1,0,0,0,1191,1202,3,192,96,0,1192,1194,10,2,0,0,1193,1195,5,153, + 0,0,1194,1193,1,0,0,0,1194,1195,1,0,0,0,1195,1196,1,0,0,0,1196,1198, + 5,115,0,0,1197,1199,7,3,0,0,1198,1197,1,0,0,0,1198,1199,1,0,0,0, + 1199,1200,1,0,0,0,1200,1202,3,192,96,0,1201,1174,1,0,0,0,1201,1183, + 1,0,0,0,1201,1192,1,0,0,0,1202,1205,1,0,0,0,1203,1201,1,0,0,0,1203, + 1204,1,0,0,0,1204,191,1,0,0,0,1205,1203,1,0,0,0,1206,1208,3,94,47, + 0,1207,1209,3,124,62,0,1208,1207,1,0,0,0,1208,1209,1,0,0,0,1209, + 1210,1,0,0,0,1210,1212,3,130,65,0,1211,1213,3,102,51,0,1212,1211, + 1,0,0,0,1212,1213,1,0,0,0,1213,1215,1,0,0,0,1214,1216,3,132,66,0, + 1215,1214,1,0,0,0,1215,1216,1,0,0,0,1216,1218,1,0,0,0,1217,1219, + 3,110,55,0,1218,1217,1,0,0,0,1218,1219,1,0,0,0,1219,1221,1,0,0,0, + 1220,1222,3,122,61,0,1221,1220,1,0,0,0,1221,1222,1,0,0,0,1222,1224, + 1,0,0,0,1223,1225,3,106,53,0,1224,1223,1,0,0,0,1224,1225,1,0,0,0, + 1225,1227,1,0,0,0,1226,1228,3,136,68,0,1227,1226,1,0,0,0,1227,1228, + 1,0,0,0,1228,1230,1,0,0,0,1229,1231,3,134,67,0,1230,1229,1,0,0,0, + 1230,1231,1,0,0,0,1231,1234,1,0,0,0,1232,1234,3,194,97,0,1233,1206, + 1,0,0,0,1233,1232,1,0,0,0,1234,193,1,0,0,0,1235,1236,6,97,-1,0,1236, + 1237,3,196,98,0,1237,1243,1,0,0,0,1238,1239,10,2,0,0,1239,1240,5, + 151,0,0,1240,1242,3,196,98,0,1241,1238,1,0,0,0,1242,1245,1,0,0,0, + 1243,1241,1,0,0,0,1243,1244,1,0,0,0,1244,195,1,0,0,0,1245,1243,1, + 0,0,0,1246,1247,6,98,-1,0,1247,1248,3,198,99,0,1248,1254,1,0,0,0, + 1249,1250,10,2,0,0,1250,1251,5,7,0,0,1251,1253,3,198,99,0,1252,1249, + 1,0,0,0,1253,1256,1,0,0,0,1254,1252,1,0,0,0,1254,1255,1,0,0,0,1255, + 197,1,0,0,0,1256,1254,1,0,0,0,1257,1258,5,140,0,0,1258,1261,3,198, + 99,0,1259,1261,3,200,100,0,1260,1257,1,0,0,0,1260,1259,1,0,0,0,1261, + 199,1,0,0,0,1262,1263,6,100,-1,0,1263,1264,3,202,101,0,1264,1310, + 1,0,0,0,1265,1266,10,7,0,0,1266,1267,7,8,0,0,1267,1309,3,202,101, + 0,1268,1269,10,6,0,0,1269,1271,5,118,0,0,1270,1272,5,140,0,0,1271, + 1270,1,0,0,0,1271,1272,1,0,0,0,1272,1273,1,0,0,0,1273,1309,3,278, + 139,0,1274,1276,10,5,0,0,1275,1277,5,140,0,0,1276,1275,1,0,0,0,1276, + 1277,1,0,0,0,1277,1278,1,0,0,0,1278,1279,5,106,0,0,1279,1280,5,294, + 0,0,1280,1281,3,188,94,0,1281,1282,5,295,0,0,1282,1309,1,0,0,0,1283, + 1285,10,4,0,0,1284,1286,5,140,0,0,1285,1284,1,0,0,0,1285,1286,1, + 0,0,0,1286,1287,1,0,0,0,1287,1288,5,106,0,0,1288,1309,3,202,101, + 0,1289,1291,10,3,0,0,1290,1292,5,140,0,0,1291,1290,1,0,0,0,1291, + 1292,1,0,0,0,1292,1293,1,0,0,0,1293,1294,5,127,0,0,1294,1297,3,202, + 101,0,1295,1296,5,74,0,0,1296,1298,3,188,94,0,1297,1295,1,0,0,0, + 1297,1298,1,0,0,0,1298,1309,1,0,0,0,1299,1301,10,2,0,0,1300,1302, + 5,140,0,0,1301,1300,1,0,0,0,1301,1302,1,0,0,0,1302,1303,1,0,0,0, + 1303,1304,5,17,0,0,1304,1305,3,202,101,0,1305,1306,5,7,0,0,1306, + 1307,3,202,101,0,1307,1309,1,0,0,0,1308,1265,1,0,0,0,1308,1268,1, + 0,0,0,1308,1274,1,0,0,0,1308,1283,1,0,0,0,1308,1289,1,0,0,0,1308, + 1299,1,0,0,0,1309,1312,1,0,0,0,1310,1308,1,0,0,0,1310,1311,1,0,0, + 0,1311,201,1,0,0,0,1312,1310,1,0,0,0,1313,1314,6,101,-1,0,1314,1315, + 3,204,102,0,1315,1321,1,0,0,0,1316,1317,10,2,0,0,1317,1318,7,9,0, + 0,1318,1320,3,204,102,0,1319,1316,1,0,0,0,1320,1323,1,0,0,0,1321, + 1319,1,0,0,0,1321,1322,1,0,0,0,1322,203,1,0,0,0,1323,1321,1,0,0, + 0,1324,1325,6,102,-1,0,1325,1326,3,206,103,0,1326,1332,1,0,0,0,1327, + 1328,10,2,0,0,1328,1329,7,10,0,0,1329,1331,3,206,103,0,1330,1327, + 1,0,0,0,1331,1334,1,0,0,0,1332,1330,1,0,0,0,1332,1333,1,0,0,0,1333, + 205,1,0,0,0,1334,1332,1,0,0,0,1335,1336,6,103,-1,0,1336,1337,3,208, + 104,0,1337,1343,1,0,0,0,1338,1339,10,2,0,0,1339,1340,7,11,0,0,1340, + 1342,3,208,104,0,1341,1338,1,0,0,0,1342,1345,1,0,0,0,1343,1341,1, + 0,0,0,1343,1344,1,0,0,0,1344,207,1,0,0,0,1345,1343,1,0,0,0,1346, + 1347,7,10,0,0,1347,1350,3,208,104,0,1348,1350,3,210,105,0,1349,1346, + 1,0,0,0,1349,1348,1,0,0,0,1350,209,1,0,0,0,1351,1352,6,105,-1,0, + 1352,1373,3,212,106,0,1353,1373,3,238,119,0,1354,1373,3,226,113, + 0,1355,1373,3,228,114,0,1356,1373,3,230,115,0,1357,1373,3,232,116, + 0,1358,1373,3,242,121,0,1359,1373,3,240,120,0,1360,1373,3,244,122, + 0,1361,1373,3,216,108,0,1362,1373,3,248,124,0,1363,1373,3,234,117, + 0,1364,1373,3,246,123,0,1365,1373,3,250,125,0,1366,1373,3,214,107, + 0,1367,1373,3,256,128,0,1368,1373,3,218,109,0,1369,1373,3,224,112, + 0,1370,1373,3,220,110,0,1371,1373,3,236,118,0,1372,1351,1,0,0,0, + 1372,1353,1,0,0,0,1372,1354,1,0,0,0,1372,1355,1,0,0,0,1372,1356, + 1,0,0,0,1372,1357,1,0,0,0,1372,1358,1,0,0,0,1372,1359,1,0,0,0,1372, + 1360,1,0,0,0,1372,1361,1,0,0,0,1372,1362,1,0,0,0,1372,1363,1,0,0, + 0,1372,1364,1,0,0,0,1372,1365,1,0,0,0,1372,1366,1,0,0,0,1372,1367, + 1,0,0,0,1372,1368,1,0,0,0,1372,1369,1,0,0,0,1372,1370,1,0,0,0,1372, + 1371,1,0,0,0,1373,1382,1,0,0,0,1374,1376,10,6,0,0,1375,1377,3,254, + 127,0,1376,1375,1,0,0,0,1377,1378,1,0,0,0,1378,1376,1,0,0,0,1378, + 1379,1,0,0,0,1379,1381,1,0,0,0,1380,1374,1,0,0,0,1381,1384,1,0,0, + 0,1382,1380,1,0,0,0,1382,1383,1,0,0,0,1383,211,1,0,0,0,1384,1382, + 1,0,0,0,1385,1386,5,294,0,0,1386,1387,3,188,94,0,1387,1388,5,295, + 0,0,1388,1397,1,0,0,0,1389,1397,5,51,0,0,1390,1397,5,48,0,0,1391, + 1397,3,260,130,0,1392,1397,3,262,131,0,1393,1397,3,276,138,0,1394, + 1397,3,266,133,0,1395,1397,3,272,136,0,1396,1385,1,0,0,0,1396,1389, + 1,0,0,0,1396,1390,1,0,0,0,1396,1391,1,0,0,0,1396,1392,1,0,0,0,1396, + 1393,1,0,0,0,1396,1394,1,0,0,0,1396,1395,1,0,0,0,1397,213,1,0,0, + 0,1398,1399,5,143,0,0,1399,1400,5,294,0,0,1400,1401,3,188,94,0,1401, + 1402,5,270,0,0,1402,1403,3,188,94,0,1403,1404,5,295,0,0,1404,215, + 1,0,0,0,1405,1406,5,32,0,0,1406,1407,5,294,0,0,1407,1412,3,188,94, + 0,1408,1409,5,270,0,0,1409,1411,3,188,94,0,1410,1408,1,0,0,0,1411, + 1414,1,0,0,0,1412,1410,1,0,0,0,1412,1413,1,0,0,0,1413,1415,1,0,0, + 0,1414,1412,1,0,0,0,1415,1416,5,295,0,0,1416,217,1,0,0,0,1417,1419, + 5,23,0,0,1418,1420,3,188,94,0,1419,1418,1,0,0,0,1419,1420,1,0,0, + 0,1420,1426,1,0,0,0,1421,1422,5,223,0,0,1422,1423,3,188,94,0,1423, + 1424,5,200,0,0,1424,1425,3,188,94,0,1425,1427,1,0,0,0,1426,1421, + 1,0,0,0,1427,1428,1,0,0,0,1428,1426,1,0,0,0,1428,1429,1,0,0,0,1429, + 1432,1,0,0,0,1430,1431,5,71,0,0,1431,1433,3,188,94,0,1432,1430,1, + 0,0,0,1432,1433,1,0,0,0,1433,1434,1,0,0,0,1434,1435,5,72,0,0,1435, + 219,1,0,0,0,1436,1437,5,219,0,0,1437,1442,3,222,111,0,1438,1439, + 5,270,0,0,1439,1441,3,222,111,0,1440,1438,1,0,0,0,1441,1444,1,0, + 0,0,1442,1440,1,0,0,0,1442,1443,1,0,0,0,1443,221,1,0,0,0,1444,1442, + 1,0,0,0,1445,1446,5,294,0,0,1446,1451,3,188,94,0,1447,1448,5,270, + 0,0,1448,1450,3,188,94,0,1449,1447,1,0,0,0,1450,1453,1,0,0,0,1451, + 1449,1,0,0,0,1451,1452,1,0,0,0,1452,1454,1,0,0,0,1453,1451,1,0,0, + 0,1454,1455,5,295,0,0,1455,223,1,0,0,0,1456,1457,5,294,0,0,1457, + 1460,3,188,94,0,1458,1459,5,270,0,0,1459,1461,3,188,94,0,1460,1458, + 1,0,0,0,1461,1462,1,0,0,0,1462,1460,1,0,0,0,1462,1463,1,0,0,0,1463, + 1464,1,0,0,0,1464,1465,5,295,0,0,1465,225,1,0,0,0,1466,1467,7,12, + 0,0,1467,1476,5,294,0,0,1468,1473,3,188,94,0,1469,1470,5,270,0,0, + 1470,1472,3,188,94,0,1471,1469,1,0,0,0,1472,1475,1,0,0,0,1473,1471, + 1,0,0,0,1473,1474,1,0,0,0,1474,1477,1,0,0,0,1475,1473,1,0,0,0,1476, + 1468,1,0,0,0,1476,1477,1,0,0,0,1477,1478,1,0,0,0,1478,1479,5,295, + 0,0,1479,227,1,0,0,0,1480,1481,5,195,0,0,1481,1482,5,294,0,0,1482, + 1489,3,188,94,0,1483,1484,5,270,0,0,1484,1487,3,188,94,0,1485,1486, + 5,270,0,0,1486,1488,3,188,94,0,1487,1485,1,0,0,0,1487,1488,1,0,0, + 0,1488,1490,1,0,0,0,1489,1483,1,0,0,0,1489,1490,1,0,0,0,1490,1491, + 1,0,0,0,1491,1492,5,295,0,0,1492,1507,1,0,0,0,1493,1494,5,195,0, + 0,1494,1495,5,294,0,0,1495,1502,3,188,94,0,1496,1497,5,95,0,0,1497, + 1500,3,188,94,0,1498,1499,5,92,0,0,1499,1501,3,188,94,0,1500,1498, + 1,0,0,0,1500,1501,1,0,0,0,1501,1503,1,0,0,0,1502,1496,1,0,0,0,1502, + 1503,1,0,0,0,1503,1504,1,0,0,0,1504,1505,5,295,0,0,1505,1507,1,0, + 0,0,1506,1480,1,0,0,0,1506,1493,1,0,0,0,1507,229,1,0,0,0,1508,1509, + 5,160,0,0,1509,1510,5,294,0,0,1510,1511,3,188,94,0,1511,1512,5,270, + 0,0,1512,1513,3,188,94,0,1513,1514,5,295,0,0,1514,1523,1,0,0,0,1515, + 1516,5,160,0,0,1516,1517,5,294,0,0,1517,1518,3,188,94,0,1518,1519, + 5,106,0,0,1519,1520,3,188,94,0,1520,1521,5,295,0,0,1521,1523,1,0, + 0,0,1522,1508,1,0,0,0,1522,1515,1,0,0,0,1523,231,1,0,0,0,1524,1525, + 5,156,0,0,1525,1526,5,294,0,0,1526,1527,3,188,94,0,1527,1528,5,270, + 0,0,1528,1529,3,188,94,0,1529,1530,5,270,0,0,1530,1533,3,188,94, + 0,1531,1532,5,270,0,0,1532,1534,3,188,94,0,1533,1531,1,0,0,0,1533, + 1534,1,0,0,0,1534,1535,1,0,0,0,1535,1536,5,295,0,0,1536,1551,1,0, + 0,0,1537,1538,5,156,0,0,1538,1539,5,294,0,0,1539,1540,3,188,94,0, + 1540,1541,5,159,0,0,1541,1542,3,188,94,0,1542,1543,5,95,0,0,1543, + 1546,3,188,94,0,1544,1545,5,92,0,0,1545,1547,3,188,94,0,1546,1544, + 1,0,0,0,1546,1547,1,0,0,0,1547,1548,1,0,0,0,1548,1549,5,295,0,0, + 1549,1551,1,0,0,0,1550,1524,1,0,0,0,1550,1537,1,0,0,0,1551,233,1, + 0,0,0,1552,1553,5,44,0,0,1553,1554,5,294,0,0,1554,1555,5,277,0,0, + 1555,1565,5,295,0,0,1556,1557,7,13,0,0,1557,1559,5,294,0,0,1558, + 1560,3,100,50,0,1559,1558,1,0,0,0,1559,1560,1,0,0,0,1560,1561,1, + 0,0,0,1561,1562,3,188,94,0,1562,1563,5,295,0,0,1563,1565,1,0,0,0, + 1564,1552,1,0,0,0,1564,1556,1,0,0,0,1565,235,1,0,0,0,1566,1567,7, + 14,0,0,1567,1568,5,294,0,0,1568,1575,3,188,94,0,1569,1570,5,270, + 0,0,1570,1573,3,188,94,0,1571,1572,5,270,0,0,1572,1574,3,188,94, + 0,1573,1571,1,0,0,0,1573,1574,1,0,0,0,1574,1576,1,0,0,0,1575,1569, + 1,0,0,0,1575,1576,1,0,0,0,1576,1577,1,0,0,0,1577,1578,5,295,0,0, + 1578,1579,3,116,58,0,1579,237,1,0,0,0,1580,1581,5,24,0,0,1581,1582, + 5,294,0,0,1582,1583,3,188,94,0,1583,1584,5,10,0,0,1584,1585,3,278, + 139,0,1585,1586,5,295,0,0,1586,239,1,0,0,0,1587,1588,5,235,0,0,1588, + 1589,5,294,0,0,1589,1590,3,188,94,0,1590,1591,5,10,0,0,1591,1592, + 3,278,139,0,1592,1593,5,295,0,0,1593,241,1,0,0,0,1594,1595,5,234, + 0,0,1595,1596,5,294,0,0,1596,1597,3,188,94,0,1597,1598,5,10,0,0, + 1598,1599,3,278,139,0,1599,1600,5,295,0,0,1600,243,1,0,0,0,1601, + 1602,5,85,0,0,1602,1603,5,294,0,0,1603,1604,5,303,0,0,1604,1605, + 5,95,0,0,1605,1606,3,188,94,0,1606,1607,5,295,0,0,1607,245,1,0,0, + 0,1608,1609,5,207,0,0,1609,1617,5,294,0,0,1610,1612,5,303,0,0,1611, + 1610,1,0,0,0,1611,1612,1,0,0,0,1612,1614,1,0,0,0,1613,1615,3,188, + 94,0,1614,1613,1,0,0,0,1614,1615,1,0,0,0,1615,1616,1,0,0,0,1616, + 1618,5,95,0,0,1617,1611,1,0,0,0,1617,1618,1,0,0,0,1618,1619,1,0, + 0,0,1619,1620,3,188,94,0,1620,1621,5,295,0,0,1621,247,1,0,0,0,1622, + 1623,7,15,0,0,1623,1624,5,294,0,0,1624,1625,5,303,0,0,1625,1626, + 5,270,0,0,1626,1627,3,188,94,0,1627,1628,5,270,0,0,1628,1629,3,188, + 94,0,1629,1630,5,295,0,0,1630,249,1,0,0,0,1631,1632,3,252,126,0, + 1632,1641,5,294,0,0,1633,1638,3,188,94,0,1634,1635,5,270,0,0,1635, + 1637,3,188,94,0,1636,1634,1,0,0,0,1637,1640,1,0,0,0,1638,1636,1, + 0,0,0,1638,1639,1,0,0,0,1639,1642,1,0,0,0,1640,1638,1,0,0,0,1641, + 1633,1,0,0,0,1641,1642,1,0,0,0,1642,1643,1,0,0,0,1643,1644,5,295, + 0,0,1644,251,1,0,0,0,1645,1646,3,12,6,0,1646,1647,5,299,0,0,1647, + 1649,1,0,0,0,1648,1645,1,0,0,0,1649,1652,1,0,0,0,1650,1648,1,0,0, + 0,1650,1651,1,0,0,0,1651,1653,1,0,0,0,1652,1650,1,0,0,0,1653,1664, + 7,16,0,0,1654,1655,3,12,6,0,1655,1656,5,299,0,0,1656,1658,1,0,0, + 0,1657,1654,1,0,0,0,1658,1661,1,0,0,0,1659,1657,1,0,0,0,1659,1660, + 1,0,0,0,1660,1662,1,0,0,0,1661,1659,1,0,0,0,1662,1664,3,12,6,0,1663, + 1650,1,0,0,0,1663,1659,1,0,0,0,1664,253,1,0,0,0,1665,1666,5,290, + 0,0,1666,1667,3,188,94,0,1667,1668,5,291,0,0,1668,1677,1,0,0,0,1669, + 1670,5,290,0,0,1670,1671,5,277,0,0,1671,1677,5,291,0,0,1672,1673, + 5,299,0,0,1673,1677,3,12,6,0,1674,1675,5,299,0,0,1675,1677,5,277, + 0,0,1676,1665,1,0,0,0,1676,1669,1,0,0,0,1676,1672,1,0,0,0,1676,1674, + 1,0,0,0,1677,255,1,0,0,0,1678,1679,5,294,0,0,1679,1680,3,210,105, + 0,1680,1681,5,130,0,0,1681,1682,3,140,70,0,1682,1683,5,295,0,0,1683, + 257,1,0,0,0,1684,1685,3,210,105,0,1685,1686,5,130,0,0,1686,1687, + 3,138,69,0,1687,259,1,0,0,0,1688,1689,5,298,0,0,1689,261,1,0,0,0, + 1690,1692,5,275,0,0,1691,1690,1,0,0,0,1691,1692,1,0,0,0,1692,1693, + 1,0,0,0,1693,1699,7,0,0,0,1694,1696,5,275,0,0,1695,1694,1,0,0,0, + 1695,1696,1,0,0,0,1696,1697,1,0,0,0,1697,1699,3,264,132,0,1698,1691, + 1,0,0,0,1698,1695,1,0,0,0,1699,263,1,0,0,0,1700,1701,5,79,0,0,1701, + 265,1,0,0,0,1702,1705,3,268,134,0,1703,1705,3,270,135,0,1704,1702, + 1,0,0,0,1704,1703,1,0,0,0,1705,267,1,0,0,0,1706,1715,5,290,0,0,1707, + 1712,3,188,94,0,1708,1709,5,270,0,0,1709,1711,3,188,94,0,1710,1708, + 1,0,0,0,1711,1714,1,0,0,0,1712,1710,1,0,0,0,1712,1713,1,0,0,0,1713, + 1716,1,0,0,0,1714,1712,1,0,0,0,1715,1707,1,0,0,0,1715,1716,1,0,0, + 0,1716,1717,1,0,0,0,1717,1718,5,291,0,0,1718,269,1,0,0,0,1719,1728, + 5,288,0,0,1720,1725,3,188,94,0,1721,1722,5,270,0,0,1722,1724,3,188, + 94,0,1723,1721,1,0,0,0,1724,1727,1,0,0,0,1725,1723,1,0,0,0,1725, + 1726,1,0,0,0,1726,1729,1,0,0,0,1727,1725,1,0,0,0,1728,1720,1,0,0, + 0,1728,1729,1,0,0,0,1729,1730,1,0,0,0,1730,1731,5,289,0,0,1731,271, + 1,0,0,0,1732,1741,5,292,0,0,1733,1738,3,274,137,0,1734,1735,5,270, + 0,0,1735,1737,3,274,137,0,1736,1734,1,0,0,0,1737,1740,1,0,0,0,1738, + 1736,1,0,0,0,1738,1739,1,0,0,0,1739,1742,1,0,0,0,1740,1738,1,0,0, + 0,1741,1733,1,0,0,0,1741,1742,1,0,0,0,1742,1743,1,0,0,0,1743,1744, + 5,293,0,0,1744,273,1,0,0,0,1745,1746,3,188,94,0,1746,1747,5,296, + 0,0,1747,1748,3,188,94,0,1748,275,1,0,0,0,1749,1784,5,141,0,0,1750, + 1784,5,236,0,0,1751,1784,5,208,0,0,1752,1784,5,88,0,0,1753,1784, + 5,300,0,0,1754,1784,5,301,0,0,1755,1784,5,302,0,0,1756,1784,5,309, + 0,0,1757,1758,5,53,0,0,1758,1784,5,300,0,0,1759,1763,5,201,0,0,1760, + 1761,5,294,0,0,1761,1762,5,301,0,0,1762,1764,5,295,0,0,1763,1760, + 1,0,0,0,1763,1764,1,0,0,0,1764,1768,1,0,0,0,1765,1766,5,226,0,0, + 1766,1767,5,201,0,0,1767,1769,5,229,0,0,1768,1765,1,0,0,0,1768,1769, + 1,0,0,0,1769,1770,1,0,0,0,1770,1784,5,300,0,0,1771,1775,5,202,0, + 0,1772,1773,5,294,0,0,1773,1774,5,301,0,0,1774,1776,5,295,0,0,1775, + 1772,1,0,0,0,1775,1776,1,0,0,0,1776,1780,1,0,0,0,1777,1778,5,226, + 0,0,1778,1779,5,201,0,0,1779,1781,5,229,0,0,1780,1777,1,0,0,0,1780, + 1781,1,0,0,0,1781,1782,1,0,0,0,1782,1784,5,300,0,0,1783,1749,1,0, + 0,0,1783,1750,1,0,0,0,1783,1751,1,0,0,0,1783,1752,1,0,0,0,1783,1753, + 1,0,0,0,1783,1754,1,0,0,0,1783,1755,1,0,0,0,1783,1756,1,0,0,0,1783, + 1757,1,0,0,0,1783,1759,1,0,0,0,1783,1771,1,0,0,0,1784,277,1,0,0, + 0,1785,1824,7,17,0,0,1786,1787,5,69,0,0,1787,1824,5,161,0,0,1788, + 1792,7,18,0,0,1789,1790,5,294,0,0,1790,1791,5,301,0,0,1791,1793, + 5,295,0,0,1792,1789,1,0,0,0,1792,1793,1,0,0,0,1793,1824,1,0,0,0, + 1794,1795,5,27,0,0,1795,1799,5,221,0,0,1796,1797,5,294,0,0,1797, + 1798,5,301,0,0,1798,1800,5,295,0,0,1799,1796,1,0,0,0,1799,1800,1, + 0,0,0,1800,1824,1,0,0,0,1801,1809,7,19,0,0,1802,1803,5,294,0,0,1803, + 1806,5,301,0,0,1804,1805,5,270,0,0,1805,1807,5,301,0,0,1806,1804, + 1,0,0,0,1806,1807,1,0,0,0,1807,1808,1,0,0,0,1808,1810,5,295,0,0, + 1809,1802,1,0,0,0,1809,1810,1,0,0,0,1810,1824,1,0,0,0,1811,1815, + 7,20,0,0,1812,1813,5,294,0,0,1813,1814,5,301,0,0,1814,1816,5,295, + 0,0,1815,1812,1,0,0,0,1815,1816,1,0,0,0,1816,1820,1,0,0,0,1817,1818, + 5,226,0,0,1818,1819,5,201,0,0,1819,1821,5,229,0,0,1820,1817,1,0, + 0,0,1820,1821,1,0,0,0,1821,1824,1,0,0,0,1822,1824,3,12,6,0,1823, + 1785,1,0,0,0,1823,1786,1,0,0,0,1823,1788,1,0,0,0,1823,1794,1,0,0, + 0,1823,1801,1,0,0,0,1823,1811,1,0,0,0,1823,1822,1,0,0,0,1824,279, + 1,0,0,0,230,287,292,294,301,305,309,313,315,340,343,350,365,374, + 386,391,402,409,417,422,429,435,438,441,445,450,453,458,466,472, + 485,491,499,513,516,519,525,529,535,539,541,549,557,568,571,586, + 594,606,611,616,627,637,640,648,657,662,665,668,674,681,686,691, + 700,707,712,715,725,739,744,748,752,760,764,773,778,781,792,802, + 814,821,836,851,856,863,867,870,875,881,887,892,894,903,907,910, + 916,920,922,926,929,934,937,941,945,948,953,956,960,962,969,972, + 1008,1012,1016,1019,1031,1042,1048,1056,1064,1068,1070,1078,1082, + 1092,1098,1100,1105,1112,1115,1118,1122,1125,1128,1130,1135,1138, + 1141,1148,1156,1160,1164,1167,1176,1180,1185,1189,1194,1198,1201, + 1203,1208,1212,1215,1218,1221,1224,1227,1230,1233,1243,1254,1260, + 1271,1276,1285,1291,1297,1301,1308,1310,1321,1332,1343,1349,1372, + 1378,1382,1396,1412,1419,1428,1432,1442,1451,1462,1473,1476,1487, + 1489,1500,1502,1506,1522,1533,1546,1550,1559,1564,1573,1575,1611, + 1614,1617,1638,1641,1650,1659,1663,1676,1691,1695,1698,1704,1712, + 1715,1725,1728,1738,1741,1763,1768,1775,1780,1783,1792,1799,1806, + 1809,1815,1820,1823 ] class PartiQLParser ( Parser ): @@ -911,115 +923,116 @@ class PartiQLParser ( Parser ): RULE_removeCommand = 27 RULE_insertCommandReturning = 28 RULE_insertStatement = 29 - RULE_onConflict = 30 - RULE_insertStatementLegacy = 31 - RULE_onConflictLegacy = 32 - RULE_conflictTarget = 33 - RULE_constraintName = 34 - RULE_conflictAction = 35 - RULE_doReplace = 36 - RULE_doUpdate = 37 - RULE_updateClause = 38 - RULE_setCommand = 39 - RULE_setAssignment = 40 - RULE_deleteCommand = 41 - RULE_returningClause = 42 - RULE_returningColumn = 43 - RULE_fromClauseSimple = 44 - RULE_whereClause = 45 - RULE_selectClause = 46 - RULE_projectionItems = 47 - RULE_projectionItem = 48 - RULE_setQuantifierStrategy = 49 - RULE_letClause = 50 - RULE_letBinding = 51 - RULE_orderByClause = 52 - RULE_orderSortSpec = 53 - RULE_groupClause = 54 - RULE_groupAlias = 55 - RULE_groupKey = 56 - RULE_over = 57 - RULE_windowPartitionList = 58 - RULE_windowSortSpecList = 59 - RULE_havingClause = 60 - RULE_excludeClause = 61 - RULE_excludeExpr = 62 - RULE_excludeExprSteps = 63 - RULE_fromClause = 64 - RULE_whereClauseSelect = 65 - RULE_offsetByClause = 66 - RULE_limitClause = 67 - RULE_gpmlPattern = 68 - RULE_gpmlPatternList = 69 - RULE_matchPattern = 70 - RULE_graphPart = 71 - RULE_matchSelector = 72 - RULE_patternPathVariable = 73 - RULE_patternRestrictor = 74 - RULE_node = 75 - RULE_edge = 76 - RULE_pattern = 77 - RULE_patternQuantifier = 78 - RULE_edgeWSpec = 79 - RULE_edgeSpec = 80 - RULE_labelSpec = 81 - RULE_labelTerm = 82 - RULE_labelFactor = 83 - RULE_labelPrimary = 84 - RULE_edgeAbbrev = 85 - RULE_tableReference = 86 - RULE_tableNonJoin = 87 - RULE_tableBaseReference = 88 - RULE_tableUnpivot = 89 - RULE_joinRhs = 90 - RULE_joinSpec = 91 - RULE_joinType = 92 - RULE_expr = 93 - RULE_exprBagOp = 94 - RULE_exprSelect = 95 - RULE_exprOr = 96 - RULE_exprAnd = 97 - RULE_exprNot = 98 - RULE_exprPredicate = 99 - RULE_mathOp00 = 100 - RULE_mathOp01 = 101 - RULE_mathOp02 = 102 - RULE_valueExpr = 103 - RULE_exprPrimary = 104 - RULE_exprTerm = 105 - RULE_nullIf = 106 - RULE_coalesce = 107 - RULE_caseExpr = 108 - RULE_values = 109 - RULE_valueRow = 110 - RULE_valueList = 111 - RULE_sequenceConstructor = 112 - RULE_substring = 113 - RULE_position = 114 - RULE_overlay = 115 - RULE_aggregate = 116 - RULE_windowFunction = 117 - RULE_cast = 118 - RULE_canLosslessCast = 119 - RULE_canCast = 120 - RULE_extract = 121 - RULE_trimFunction = 122 - RULE_dateFunction = 123 - RULE_functionCall = 124 - RULE_functionName = 125 - RULE_pathStep = 126 - RULE_exprGraphMatchMany = 127 - RULE_exprGraphMatchOne = 128 - RULE_parameter = 129 - RULE_varRefExpr = 130 - RULE_nonReservedKeywords = 131 - RULE_collection = 132 - RULE_array = 133 - RULE_bag = 134 - RULE_tuple = 135 - RULE_pair = 136 - RULE_literal = 137 - RULE_type = 138 + RULE_columnList = 30 + RULE_onConflict = 31 + RULE_insertStatementLegacy = 32 + RULE_onConflictLegacy = 33 + RULE_conflictTarget = 34 + RULE_constraintName = 35 + RULE_conflictAction = 36 + RULE_doReplace = 37 + RULE_doUpdate = 38 + RULE_updateClause = 39 + RULE_setCommand = 40 + RULE_setAssignment = 41 + RULE_deleteCommand = 42 + RULE_returningClause = 43 + RULE_returningColumn = 44 + RULE_fromClauseSimple = 45 + RULE_whereClause = 46 + RULE_selectClause = 47 + RULE_projectionItems = 48 + RULE_projectionItem = 49 + RULE_setQuantifierStrategy = 50 + RULE_letClause = 51 + RULE_letBinding = 52 + RULE_orderByClause = 53 + RULE_orderSortSpec = 54 + RULE_groupClause = 55 + RULE_groupAlias = 56 + RULE_groupKey = 57 + RULE_over = 58 + RULE_windowPartitionList = 59 + RULE_windowSortSpecList = 60 + RULE_havingClause = 61 + RULE_excludeClause = 62 + RULE_excludeExpr = 63 + RULE_excludeExprSteps = 64 + RULE_fromClause = 65 + RULE_whereClauseSelect = 66 + RULE_offsetByClause = 67 + RULE_limitClause = 68 + RULE_gpmlPattern = 69 + RULE_gpmlPatternList = 70 + RULE_matchPattern = 71 + RULE_graphPart = 72 + RULE_matchSelector = 73 + RULE_patternPathVariable = 74 + RULE_patternRestrictor = 75 + RULE_node = 76 + RULE_edge = 77 + RULE_pattern = 78 + RULE_patternQuantifier = 79 + RULE_edgeWSpec = 80 + RULE_edgeSpec = 81 + RULE_labelSpec = 82 + RULE_labelTerm = 83 + RULE_labelFactor = 84 + RULE_labelPrimary = 85 + RULE_edgeAbbrev = 86 + RULE_tableReference = 87 + RULE_tableNonJoin = 88 + RULE_tableBaseReference = 89 + RULE_tableUnpivot = 90 + RULE_joinRhs = 91 + RULE_joinSpec = 92 + RULE_joinType = 93 + RULE_expr = 94 + RULE_exprBagOp = 95 + RULE_exprSelect = 96 + RULE_exprOr = 97 + RULE_exprAnd = 98 + RULE_exprNot = 99 + RULE_exprPredicate = 100 + RULE_mathOp00 = 101 + RULE_mathOp01 = 102 + RULE_mathOp02 = 103 + RULE_valueExpr = 104 + RULE_exprPrimary = 105 + RULE_exprTerm = 106 + RULE_nullIf = 107 + RULE_coalesce = 108 + RULE_caseExpr = 109 + RULE_values = 110 + RULE_valueRow = 111 + RULE_valueList = 112 + RULE_sequenceConstructor = 113 + RULE_substring = 114 + RULE_position = 115 + RULE_overlay = 116 + RULE_aggregate = 117 + RULE_windowFunction = 118 + RULE_cast = 119 + RULE_canLosslessCast = 120 + RULE_canCast = 121 + RULE_extract = 122 + RULE_trimFunction = 123 + RULE_dateFunction = 124 + RULE_functionCall = 125 + RULE_functionName = 126 + RULE_pathStep = 127 + RULE_exprGraphMatchMany = 128 + RULE_exprGraphMatchOne = 129 + RULE_parameter = 130 + RULE_varRefExpr = 131 + RULE_nonReservedKeywords = 132 + RULE_collection = 133 + RULE_array = 134 + RULE_bag = 135 + RULE_tuple = 136 + RULE_pair = 137 + RULE_literal = 138 + RULE_type = 139 ruleNames = [ "root", "statement", "explainOption", "asIdent", "atIdent", "byIdent", "symbolPrimitive", "dql", "execCommand", "qualifiedName", @@ -1028,10 +1041,10 @@ class PartiQLParser ( Parser ): "columnConstraint", "columnConstraintDef", "dml", "dmlBaseCommand", "pathSimple", "pathSimpleSteps", "replaceCommand", "upsertCommand", "removeCommand", "insertCommandReturning", "insertStatement", - "onConflict", "insertStatementLegacy", "onConflictLegacy", - "conflictTarget", "constraintName", "conflictAction", - "doReplace", "doUpdate", "updateClause", "setCommand", - "setAssignment", "deleteCommand", "returningClause", + "columnList", "onConflict", "insertStatementLegacy", + "onConflictLegacy", "conflictTarget", "constraintName", + "conflictAction", "doReplace", "doUpdate", "updateClause", + "setCommand", "setAssignment", "deleteCommand", "returningClause", "returningColumn", "fromClauseSimple", "whereClause", "selectClause", "projectionItems", "projectionItem", "setQuantifierStrategy", "letClause", "letBinding", "orderByClause", @@ -1441,41 +1454,41 @@ def root(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 292 + self.state = 294 self._errHandler.sync(self) _la = self._input.LA(1) if _la==83: - self.state = 278 + self.state = 280 self.match(PartiQLParser.EXPLAIN) - self.state = 290 + self.state = 292 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,1,self._ctx) if la_ == 1: - self.state = 279 + self.state = 281 self.match(PartiQLParser.PAREN_LEFT) - self.state = 280 + self.state = 282 self.explainOption() - self.state = 285 + self.state = 287 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 281 + self.state = 283 self.match(PartiQLParser.COMMA) - self.state = 282 + self.state = 284 self.explainOption() - self.state = 287 + self.state = 289 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 288 + self.state = 290 self.match(PartiQLParser.PAREN_RIGHT) - self.state = 294 + self.state = 296 self.statement() - self.state = 295 + self.state = 297 self.match(PartiQLParser.EOF) except RecognitionException as re: localctx.exception = re @@ -1618,19 +1631,19 @@ def statement(self): self.enterRule(localctx, 2, self.RULE_statement) self._la = 0 # Token type try: - self.state = 313 + self.state = 315 self._errHandler.sync(self) token = self._input.LA(1) if token in [8, 15, 19, 23, 24, 28, 29, 32, 44, 48, 51, 53, 75, 79, 82, 85, 86, 87, 88, 129, 131, 132, 140, 141, 143, 145, 156, 160, 182, 187, 189, 195, 196, 201, 202, 207, 208, 213, 219, 230, 231, 234, 235, 236, 237, 266, 267, 271, 272, 275, 288, 290, 292, 294, 298, 300, 301, 302, 303, 304, 309]: localctx = PartiQLParser.QueryDqlContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 297 - self.dql() self.state = 299 + self.dql() + self.state = 301 self._errHandler.sync(self) _la = self._input.LA(1) if _la==297: - self.state = 298 + self.state = 300 self.match(PartiQLParser.COLON_SEMI) @@ -1638,13 +1651,13 @@ def statement(self): elif token in [61, 95, 112, 173, 185, 212, 214, 241]: localctx = PartiQLParser.QueryDmlContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 301 - self.dml() self.state = 303 + self.dml() + self.state = 305 self._errHandler.sync(self) _la = self._input.LA(1) if _la==297: - self.state = 302 + self.state = 304 self.match(PartiQLParser.COLON_SEMI) @@ -1652,13 +1665,13 @@ def statement(self): elif token in [45, 70]: localctx = PartiQLParser.QueryDdlContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 305 - self.ddl() self.state = 307 + self.ddl() + self.state = 309 self._errHandler.sync(self) _la = self._input.LA(1) if _la==297: - self.state = 306 + self.state = 308 self.match(PartiQLParser.COLON_SEMI) @@ -1666,13 +1679,13 @@ def statement(self): elif token in [80]: localctx = PartiQLParser.QueryExecContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 309 - self.execCommand() self.state = 311 + self.execCommand() + self.state = 313 self._errHandler.sync(self) _la = self._input.LA(1) if _la==297: - self.state = 310 + self.state = 312 self.match(PartiQLParser.COLON_SEMI) @@ -1730,9 +1743,9 @@ def explainOption(self): self.enterRule(localctx, 4, self.RULE_explainOption) try: self.enterOuterAlt(localctx, 1) - self.state = 315 + self.state = 317 localctx.param = self.match(PartiQLParser.IDENTIFIER) - self.state = 316 + self.state = 318 localctx.value = self.match(PartiQLParser.IDENTIFIER) except RecognitionException as re: localctx.exception = re @@ -1783,9 +1796,9 @@ def asIdent(self): self.enterRule(localctx, 6, self.RULE_asIdent) try: self.enterOuterAlt(localctx, 1) - self.state = 318 + self.state = 320 self.match(PartiQLParser.AS) - self.state = 319 + self.state = 321 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -1836,9 +1849,9 @@ def atIdent(self): self.enterRule(localctx, 8, self.RULE_atIdent) try: self.enterOuterAlt(localctx, 1) - self.state = 321 + self.state = 323 self.match(PartiQLParser.AT) - self.state = 322 + self.state = 324 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -1889,9 +1902,9 @@ def byIdent(self): self.enterRule(localctx, 10, self.RULE_byIdent) try: self.enterOuterAlt(localctx, 1) - self.state = 324 + self.state = 326 self.match(PartiQLParser.BY) - self.state = 325 + self.state = 327 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -1943,7 +1956,7 @@ def symbolPrimitive(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 327 + self.state = 329 localctx.ident = self._input.LT(1) _la = self._input.LA(1) if not(_la==303 or _la==304): @@ -1997,7 +2010,7 @@ def dql(self): self.enterRule(localctx, 14, self.RULE_dql) try: self.enterOuterAlt(localctx, 1) - self.state = 329 + self.state = 331 self.expr() except RecognitionException as re: localctx.exception = re @@ -2061,27 +2074,27 @@ def execCommand(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 331 + self.state = 333 self.match(PartiQLParser.EXEC) - self.state = 332 + self.state = 334 localctx.name = self.expr() - self.state = 341 + self.state = 343 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 11558071357178112) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 234187180623281297) != 0) or ((((_la - 140)) & ~0x3f) == 0 and ((1 << (_la - 140)) & 7026323504187375659) != 0) or ((((_la - 207)) & ~0x3f) == 0 and ((1 << (_la - 207)) & 1729382258948706371) != 0) or ((((_la - 271)) & ~0x3f) == 0 and ((1 << (_la - 271)) & 291666264083) != 0): - self.state = 333 + self.state = 335 localctx._expr = self.expr() localctx.args.append(localctx._expr) - self.state = 338 + self.state = 340 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 334 + self.state = 336 self.match(PartiQLParser.COMMA) - self.state = 335 + self.state = 337 localctx._expr = self.expr() localctx.args.append(localctx._expr) - self.state = 340 + self.state = 342 self._errHandler.sync(self) _la = self._input.LA(1) @@ -2145,21 +2158,21 @@ def qualifiedName(self): self.enterRule(localctx, 18, self.RULE_qualifiedName) try: self.enterOuterAlt(localctx, 1) - self.state = 348 + self.state = 350 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,10,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 343 + self.state = 345 localctx._symbolPrimitive = self.symbolPrimitive() localctx.qualifier.append(localctx._symbolPrimitive) - self.state = 344 + self.state = 346 self.match(PartiQLParser.PERIOD) - self.state = 350 + self.state = 352 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,10,self._ctx) - self.state = 351 + self.state = 353 localctx.name = self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -2207,7 +2220,7 @@ def tableName(self): self.enterRule(localctx, 20, self.RULE_tableName) try: self.enterOuterAlt(localctx, 1) - self.state = 353 + self.state = 355 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -2255,7 +2268,7 @@ def tableConstraintName(self): self.enterRule(localctx, 22, self.RULE_tableConstraintName) try: self.enterOuterAlt(localctx, 1) - self.state = 355 + self.state = 357 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -2303,7 +2316,7 @@ def columnName(self): self.enterRule(localctx, 24, self.RULE_columnName) try: self.enterOuterAlt(localctx, 1) - self.state = 357 + self.state = 359 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -2351,7 +2364,7 @@ def columnConstraintName(self): self.enterRule(localctx, 26, self.RULE_columnConstraintName) try: self.enterOuterAlt(localctx, 1) - self.state = 359 + self.state = 361 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -2402,17 +2415,17 @@ def ddl(self): localctx = PartiQLParser.DdlContext(self, self._ctx, self.state) self.enterRule(localctx, 28, self.RULE_ddl) try: - self.state = 363 + self.state = 365 self._errHandler.sync(self) token = self._input.LA(1) if token in [45]: self.enterOuterAlt(localctx, 1) - self.state = 361 + self.state = 363 self.createCommand() pass elif token in [70]: self.enterOuterAlt(localctx, 2) - self.state = 362 + self.state = 364 self.dropCommand() pass else: @@ -2533,27 +2546,27 @@ def createCommand(self): self.enterRule(localctx, 30, self.RULE_createCommand) self._la = 0 # Token type try: - self.state = 389 + self.state = 391 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,14,self._ctx) if la_ == 1: localctx = PartiQLParser.CreateTableContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 365 + self.state = 367 self.match(PartiQLParser.CREATE) - self.state = 366 + self.state = 368 self.match(PartiQLParser.TABLE) - self.state = 367 + self.state = 369 self.qualifiedName() - self.state = 372 + self.state = 374 self._errHandler.sync(self) _la = self._input.LA(1) if _la==294: - self.state = 368 + self.state = 370 self.match(PartiQLParser.PAREN_LEFT) - self.state = 369 + self.state = 371 self.tableDef() - self.state = 370 + self.state = 372 self.match(PartiQLParser.PAREN_RIGHT) @@ -2562,31 +2575,31 @@ def createCommand(self): elif la_ == 2: localctx = PartiQLParser.CreateIndexContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 374 + self.state = 376 self.match(PartiQLParser.CREATE) - self.state = 375 + self.state = 377 self.match(PartiQLParser.INDEX) - self.state = 376 + self.state = 378 self.match(PartiQLParser.ON) - self.state = 377 + self.state = 379 self.symbolPrimitive() - self.state = 378 + self.state = 380 self.match(PartiQLParser.PAREN_LEFT) - self.state = 379 + self.state = 381 self.pathSimple() - self.state = 384 + self.state = 386 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 380 + self.state = 382 self.match(PartiQLParser.COMMA) - self.state = 381 + self.state = 383 self.pathSimple() - self.state = 386 + self.state = 388 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 387 + self.state = 389 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -2688,32 +2701,32 @@ def dropCommand(self): localctx = PartiQLParser.DropCommandContext(self, self._ctx, self.state) self.enterRule(localctx, 32, self.RULE_dropCommand) try: - self.state = 400 + self.state = 402 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,15,self._ctx) if la_ == 1: localctx = PartiQLParser.DropTableContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 391 + self.state = 393 self.match(PartiQLParser.DROP) - self.state = 392 + self.state = 394 self.match(PartiQLParser.TABLE) - self.state = 393 + self.state = 395 self.qualifiedName() pass elif la_ == 2: localctx = PartiQLParser.DropIndexContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 394 + self.state = 396 self.match(PartiQLParser.DROP) - self.state = 395 + self.state = 397 self.match(PartiQLParser.INDEX) - self.state = 396 + self.state = 398 localctx.target = self.symbolPrimitive() - self.state = 397 + self.state = 399 self.match(PartiQLParser.ON) - self.state = 398 + self.state = 400 localctx.on = self.symbolPrimitive() pass @@ -2774,17 +2787,17 @@ def tableDef(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 402 + self.state = 404 self.tableDefPart() - self.state = 407 + self.state = 409 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 403 + self.state = 405 self.match(PartiQLParser.COMMA) - self.state = 404 + self.state = 406 self.tableDefPart() - self.state = 409 + self.state = 411 self._errHandler.sync(self) _la = self._input.LA(1) @@ -2857,17 +2870,17 @@ def tableDefPart(self): try: localctx = PartiQLParser.ColumnDeclarationContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 410 + self.state = 412 self.columnName() - self.state = 411 + self.state = 413 self.type_() - self.state = 415 + self.state = 417 self._errHandler.sync(self) _la = self._input.LA(1) while _la==39 or _la==140 or _la==141: - self.state = 412 + self.state = 414 self.columnConstraint() - self.state = 417 + self.state = 419 self._errHandler.sync(self) _la = self._input.LA(1) @@ -2925,17 +2938,17 @@ def columnConstraint(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 420 + self.state = 422 self._errHandler.sync(self) _la = self._input.LA(1) if _la==39: - self.state = 418 + self.state = 420 self.match(PartiQLParser.CONSTRAINT) - self.state = 419 + self.state = 421 self.columnConstraintName() - self.state = 422 + self.state = 424 self.columnConstraintDef() except RecognitionException as re: localctx.exception = re @@ -3019,21 +3032,21 @@ def columnConstraintDef(self): localctx = PartiQLParser.ColumnConstraintDefContext(self, self._ctx, self.state) self.enterRule(localctx, 40, self.RULE_columnConstraintDef) try: - self.state = 427 + self.state = 429 self._errHandler.sync(self) token = self._input.LA(1) if token in [140]: localctx = PartiQLParser.ColConstrNotNullContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 424 + self.state = 426 self.match(PartiQLParser.NOT) - self.state = 425 + self.state = 427 self.match(PartiQLParser.NULL) pass elif token in [141]: localctx = PartiQLParser.ColConstrNullContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 426 + self.state = 428 self.match(PartiQLParser.NULL) pass else: @@ -3187,39 +3200,39 @@ def dml(self): self.enterRule(localctx, 42, self.RULE_dml) self._la = 0 # Token type try: - self.state = 456 + self.state = 458 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,26,self._ctx) if la_ == 1: localctx = PartiQLParser.DmlBaseWrapperContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 429 + self.state = 431 self.updateClause() - self.state = 431 + self.state = 433 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 430 + self.state = 432 self.dmlBaseCommand() - self.state = 433 + self.state = 435 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==112 or _la==173 or ((((_la - 185)) & ~0x3f) == 0 and ((1 << (_la - 185)) & 72057594574798849) != 0)): break - self.state = 436 + self.state = 438 self._errHandler.sync(self) _la = self._input.LA(1) if _la==225: - self.state = 435 + self.state = 437 self.whereClause() - self.state = 439 + self.state = 441 self._errHandler.sync(self) _la = self._input.LA(1) if _la==246: - self.state = 438 + self.state = 440 self.returningClause() @@ -3228,33 +3241,33 @@ def dml(self): elif la_ == 2: localctx = PartiQLParser.DmlBaseWrapperContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 441 - self.fromClause() self.state = 443 + self.fromClause() + self.state = 445 self._errHandler.sync(self) _la = self._input.LA(1) if _la==225: - self.state = 442 + self.state = 444 self.whereClause() - self.state = 446 + self.state = 448 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 445 + self.state = 447 self.dmlBaseCommand() - self.state = 448 + self.state = 450 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==112 or _la==173 or ((((_la - 185)) & ~0x3f) == 0 and ((1 << (_la - 185)) & 72057594574798849) != 0)): break - self.state = 451 + self.state = 453 self._errHandler.sync(self) _la = self._input.LA(1) if _la==246: - self.state = 450 + self.state = 452 self.returningClause() @@ -3263,21 +3276,21 @@ def dml(self): elif la_ == 3: localctx = PartiQLParser.DmlDeleteContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 453 + self.state = 455 self.deleteCommand() pass elif la_ == 4: localctx = PartiQLParser.DmlInsertReturningContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 454 + self.state = 456 self.insertCommandReturning() pass elif la_ == 5: localctx = PartiQLParser.DmlBaseContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 455 + self.state = 457 self.dmlBaseCommand() pass @@ -3347,42 +3360,42 @@ def dmlBaseCommand(self): localctx = PartiQLParser.DmlBaseCommandContext(self, self._ctx, self.state) self.enterRule(localctx, 44, self.RULE_dmlBaseCommand) try: - self.state = 464 + self.state = 466 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,27,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 458 + self.state = 460 self.insertStatement() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 459 + self.state = 461 self.insertStatementLegacy() pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 460 + self.state = 462 self.setCommand() pass elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 461 + self.state = 463 self.replaceCommand() pass elif la_ == 5: self.enterOuterAlt(localctx, 5) - self.state = 462 + self.state = 464 self.removeCommand() pass elif la_ == 6: self.enterOuterAlt(localctx, 6) - self.state = 463 + self.state = 465 self.upsertCommand() pass @@ -3441,15 +3454,15 @@ def pathSimple(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 466 + self.state = 468 self.symbolPrimitive() - self.state = 470 + self.state = 472 self._errHandler.sync(self) _la = self._input.LA(1) while _la==290 or _la==299: - self.state = 467 + self.state = 469 self.pathSimpleSteps() - self.state = 472 + self.state = 474 self._errHandler.sync(self) _la = self._input.LA(1) @@ -3573,37 +3586,37 @@ def pathSimpleSteps(self): localctx = PartiQLParser.PathSimpleStepsContext(self, self._ctx, self.state) self.enterRule(localctx, 48, self.RULE_pathSimpleSteps) try: - self.state = 483 + self.state = 485 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,29,self._ctx) if la_ == 1: localctx = PartiQLParser.PathSimpleLiteralContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 473 + self.state = 475 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 474 + self.state = 476 localctx.key = self.literal() - self.state = 475 + self.state = 477 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 2: localctx = PartiQLParser.PathSimpleSymbolContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 477 + self.state = 479 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 478 + self.state = 480 localctx.key = self.symbolPrimitive() - self.state = 479 + self.state = 481 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 3: localctx = PartiQLParser.PathSimpleDotSymbolContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 481 + self.state = 483 self.match(PartiQLParser.PERIOD) - self.state = 482 + self.state = 484 localctx.key = self.symbolPrimitive() pass @@ -3670,21 +3683,21 @@ def replaceCommand(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 485 + self.state = 487 self.match(PartiQLParser.REPLACE) - self.state = 486 + self.state = 488 self.match(PartiQLParser.INTO) - self.state = 487 - self.symbolPrimitive() self.state = 489 + self.symbolPrimitive() + self.state = 491 self._errHandler.sync(self) _la = self._input.LA(1) if _la==10: - self.state = 488 + self.state = 490 self.asIdent() - self.state = 491 + self.state = 493 localctx.value = self.expr() except RecognitionException as re: localctx.exception = re @@ -3748,21 +3761,21 @@ def upsertCommand(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 493 + self.state = 495 self.match(PartiQLParser.UPSERT) - self.state = 494 + self.state = 496 self.match(PartiQLParser.INTO) - self.state = 495 - self.symbolPrimitive() self.state = 497 + self.symbolPrimitive() + self.state = 499 self._errHandler.sync(self) _la = self._input.LA(1) if _la==10: - self.state = 496 + self.state = 498 self.asIdent() - self.state = 499 + self.state = 501 localctx.value = self.expr() except RecognitionException as re: localctx.exception = re @@ -3813,9 +3826,9 @@ def removeCommand(self): self.enterRule(localctx, 54, self.RULE_removeCommand) try: self.enterOuterAlt(localctx, 1) - self.state = 501 + self.state = 503 self.match(PartiQLParser.REMOVE) - self.state = 502 + self.state = 504 self.pathSimple() except RecognitionException as re: localctx.exception = re @@ -3893,39 +3906,39 @@ def insertCommandReturning(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 504 + self.state = 506 self.match(PartiQLParser.INSERT) - self.state = 505 + self.state = 507 self.match(PartiQLParser.INTO) - self.state = 506 + self.state = 508 self.pathSimple() - self.state = 507 + self.state = 509 self.match(PartiQLParser.VALUE) - self.state = 508 + self.state = 510 localctx.value = self.expr() - self.state = 511 + self.state = 513 self._errHandler.sync(self) _la = self._input.LA(1) if _la==13: - self.state = 509 + self.state = 511 self.match(PartiQLParser.AT) - self.state = 510 + self.state = 512 localctx.pos = self.expr() - self.state = 514 + self.state = 516 self._errHandler.sync(self) _la = self._input.LA(1) if _la==147: - self.state = 513 + self.state = 515 self.onConflictLegacy() - self.state = 517 + self.state = 519 self._errHandler.sync(self) _la = self._input.LA(1) if _la==246: - self.state = 516 + self.state = 518 self.returningClause() @@ -3968,6 +3981,14 @@ def onConflict(self): return self.getTypedRuleContext(PartiQLParser.OnConflictContext,0) + def values(self): + return self.getTypedRuleContext(PartiQLParser.ValuesContext,0) + + + def columnList(self): + return self.getTypedRuleContext(PartiQLParser.ColumnListContext,0) + + def getRuleIndex(self): return PartiQLParser.RULE_insertStatement @@ -3994,31 +4015,146 @@ def insertStatement(self): self.enterRule(localctx, 58, self.RULE_insertStatement) self._la = 0 # Token type try: - self.enterOuterAlt(localctx, 1) - self.state = 519 - self.match(PartiQLParser.INSERT) - self.state = 520 - self.match(PartiQLParser.INTO) - self.state = 521 - self.symbolPrimitive() - self.state = 523 + self.state = 541 self._errHandler.sync(self) - _la = self._input.LA(1) - if _la==10: + la_ = self._interp.adaptivePredict(self._input,39,self._ctx) + if la_ == 1: + self.enterOuterAlt(localctx, 1) + self.state = 521 + self.match(PartiQLParser.INSERT) self.state = 522 - self.asIdent() + self.match(PartiQLParser.INTO) + self.state = 523 + self.symbolPrimitive() + self.state = 525 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==10: + self.state = 524 + self.asIdent() - self.state = 525 - localctx.value = self.expr() - self.state = 527 + self.state = 527 + localctx.value = self.expr() + self.state = 529 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==147: + self.state = 528 + self.onConflict() + + + pass + + elif la_ == 2: + self.enterOuterAlt(localctx, 2) + self.state = 531 + self.match(PartiQLParser.INSERT) + self.state = 532 + self.match(PartiQLParser.INTO) + self.state = 533 + self.symbolPrimitive() + self.state = 535 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==294: + self.state = 534 + self.columnList() + + + self.state = 537 + self.values() + self.state = 539 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==147: + self.state = 538 + self.onConflict() + + + pass + + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class ColumnListContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def PAREN_LEFT(self): + return self.getToken(PartiQLParser.PAREN_LEFT, 0) + + def columnName(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PartiQLParser.ColumnNameContext) + else: + return self.getTypedRuleContext(PartiQLParser.ColumnNameContext,i) + + + def PAREN_RIGHT(self): + return self.getToken(PartiQLParser.PAREN_RIGHT, 0) + + def COMMA(self, i:int=None): + if i is None: + return self.getTokens(PartiQLParser.COMMA) + else: + return self.getToken(PartiQLParser.COMMA, i) + + def getRuleIndex(self): + return PartiQLParser.RULE_columnList + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterColumnList" ): + listener.enterColumnList(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitColumnList" ): + listener.exitColumnList(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitColumnList" ): + return visitor.visitColumnList(self) + else: + return visitor.visitChildren(self) + + + + + def columnList(self): + + localctx = PartiQLParser.ColumnListContext(self, self._ctx, self.state) + self.enterRule(localctx, 60, self.RULE_columnList) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 543 + self.match(PartiQLParser.PAREN_LEFT) + self.state = 544 + self.columnName() + self.state = 549 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==147: - self.state = 526 - self.onConflict() - + while _la==270: + self.state = 545 + self.match(PartiQLParser.COMMA) + self.state = 546 + self.columnName() + self.state = 551 + self._errHandler.sync(self) + _la = self._input.LA(1) + self.state = 552 + self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -4072,23 +4208,23 @@ def accept(self, visitor:ParseTreeVisitor): def onConflict(self): localctx = PartiQLParser.OnConflictContext(self, self._ctx, self.state) - self.enterRule(localctx, 60, self.RULE_onConflict) + self.enterRule(localctx, 62, self.RULE_onConflict) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 529 + self.state = 554 self.match(PartiQLParser.ON) - self.state = 530 + self.state = 555 self.match(PartiQLParser.CONFLICT) - self.state = 532 + self.state = 557 self._errHandler.sync(self) _la = self._input.LA(1) if _la==147 or _la==294: - self.state = 531 + self.state = 556 self.conflictTarget() - self.state = 534 + self.state = 559 self.conflictAction() except RecognitionException as re: localctx.exception = re @@ -4158,35 +4294,35 @@ def accept(self, visitor:ParseTreeVisitor): def insertStatementLegacy(self): localctx = PartiQLParser.InsertStatementLegacyContext(self, self._ctx, self.state) - self.enterRule(localctx, 62, self.RULE_insertStatementLegacy) + self.enterRule(localctx, 64, self.RULE_insertStatementLegacy) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 536 + self.state = 561 self.match(PartiQLParser.INSERT) - self.state = 537 + self.state = 562 self.match(PartiQLParser.INTO) - self.state = 538 + self.state = 563 self.pathSimple() - self.state = 539 + self.state = 564 self.match(PartiQLParser.VALUE) - self.state = 540 + self.state = 565 localctx.value = self.expr() - self.state = 543 + self.state = 568 self._errHandler.sync(self) _la = self._input.LA(1) if _la==13: - self.state = 541 + self.state = 566 self.match(PartiQLParser.AT) - self.state = 542 + self.state = 567 localctx.pos = self.expr() - self.state = 546 + self.state = 571 self._errHandler.sync(self) _la = self._input.LA(1) if _la==147: - self.state = 545 + self.state = 570 self.onConflictLegacy() @@ -4248,20 +4384,20 @@ def accept(self, visitor:ParseTreeVisitor): def onConflictLegacy(self): localctx = PartiQLParser.OnConflictLegacyContext(self, self._ctx, self.state) - self.enterRule(localctx, 64, self.RULE_onConflictLegacy) + self.enterRule(localctx, 66, self.RULE_onConflictLegacy) try: self.enterOuterAlt(localctx, 1) - self.state = 548 + self.state = 573 self.match(PartiQLParser.ON) - self.state = 549 + self.state = 574 self.match(PartiQLParser.CONFLICT) - self.state = 550 + self.state = 575 self.match(PartiQLParser.WHERE) - self.state = 551 + self.state = 576 self.expr() - self.state = 552 + self.state = 577 self.match(PartiQLParser.DO) - self.state = 553 + self.state = 578 self.match(PartiQLParser.NOTHING) except RecognitionException as re: localctx.exception = re @@ -4331,40 +4467,40 @@ def accept(self, visitor:ParseTreeVisitor): def conflictTarget(self): localctx = PartiQLParser.ConflictTargetContext(self, self._ctx, self.state) - self.enterRule(localctx, 66, self.RULE_conflictTarget) + self.enterRule(localctx, 68, self.RULE_conflictTarget) self._la = 0 # Token type try: - self.state = 569 + self.state = 594 self._errHandler.sync(self) token = self._input.LA(1) if token in [294]: self.enterOuterAlt(localctx, 1) - self.state = 555 + self.state = 580 self.match(PartiQLParser.PAREN_LEFT) - self.state = 556 + self.state = 581 self.symbolPrimitive() - self.state = 561 + self.state = 586 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 557 + self.state = 582 self.match(PartiQLParser.COMMA) - self.state = 558 + self.state = 583 self.symbolPrimitive() - self.state = 563 + self.state = 588 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 564 + self.state = 589 self.match(PartiQLParser.PAREN_RIGHT) pass elif token in [147]: self.enterOuterAlt(localctx, 2) - self.state = 566 + self.state = 591 self.match(PartiQLParser.ON) - self.state = 567 + self.state = 592 self.match(PartiQLParser.CONSTRAINT) - self.state = 568 + self.state = 593 self.constraintName() pass else: @@ -4413,10 +4549,10 @@ def accept(self, visitor:ParseTreeVisitor): def constraintName(self): localctx = PartiQLParser.ConstraintNameContext(self, self._ctx, self.state) - self.enterRule(localctx, 68, self.RULE_constraintName) + self.enterRule(localctx, 70, self.RULE_constraintName) try: self.enterOuterAlt(localctx, 1) - self.state = 571 + self.state = 596 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -4477,36 +4613,36 @@ def accept(self, visitor:ParseTreeVisitor): def conflictAction(self): localctx = PartiQLParser.ConflictActionContext(self, self._ctx, self.state) - self.enterRule(localctx, 70, self.RULE_conflictAction) + self.enterRule(localctx, 72, self.RULE_conflictAction) try: - self.state = 581 + self.state = 606 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,42,self._ctx) + la_ = self._interp.adaptivePredict(self._input,46,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 573 + self.state = 598 self.match(PartiQLParser.DO) - self.state = 574 + self.state = 599 self.match(PartiQLParser.NOTHING) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 575 + self.state = 600 self.match(PartiQLParser.DO) - self.state = 576 + self.state = 601 self.match(PartiQLParser.REPLACE) - self.state = 577 + self.state = 602 self.doReplace() pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 578 + self.state = 603 self.match(PartiQLParser.DO) - self.state = 579 + self.state = 604 self.match(PartiQLParser.UPDATE) - self.state = 580 + self.state = 605 self.doUpdate() pass @@ -4561,18 +4697,18 @@ def accept(self, visitor:ParseTreeVisitor): def doReplace(self): localctx = PartiQLParser.DoReplaceContext(self, self._ctx, self.state) - self.enterRule(localctx, 72, self.RULE_doReplace) + self.enterRule(localctx, 74, self.RULE_doReplace) try: self.enterOuterAlt(localctx, 1) - self.state = 583 + self.state = 608 self.match(PartiQLParser.EXCLUDED) - self.state = 586 + self.state = 611 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,43,self._ctx) + la_ = self._interp.adaptivePredict(self._input,47,self._ctx) if la_ == 1: - self.state = 584 + self.state = 609 self.match(PartiQLParser.WHERE) - self.state = 585 + self.state = 610 localctx.condition = self.expr() @@ -4626,18 +4762,18 @@ def accept(self, visitor:ParseTreeVisitor): def doUpdate(self): localctx = PartiQLParser.DoUpdateContext(self, self._ctx, self.state) - self.enterRule(localctx, 74, self.RULE_doUpdate) + self.enterRule(localctx, 76, self.RULE_doUpdate) try: self.enterOuterAlt(localctx, 1) - self.state = 588 + self.state = 613 self.match(PartiQLParser.EXCLUDED) - self.state = 591 + self.state = 616 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,44,self._ctx) + la_ = self._interp.adaptivePredict(self._input,48,self._ctx) if la_ == 1: - self.state = 589 + self.state = 614 self.match(PartiQLParser.WHERE) - self.state = 590 + self.state = 615 localctx.condition = self.expr() @@ -4687,12 +4823,12 @@ def accept(self, visitor:ParseTreeVisitor): def updateClause(self): localctx = PartiQLParser.UpdateClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 76, self.RULE_updateClause) + self.enterRule(localctx, 78, self.RULE_updateClause) try: self.enterOuterAlt(localctx, 1) - self.state = 593 + self.state = 618 self.match(PartiQLParser.UPDATE) - self.state = 594 + self.state = 619 self.tableBaseReference() except RecognitionException as re: localctx.exception = re @@ -4749,23 +4885,23 @@ def accept(self, visitor:ParseTreeVisitor): def setCommand(self): localctx = PartiQLParser.SetCommandContext(self, self._ctx, self.state) - self.enterRule(localctx, 78, self.RULE_setCommand) + self.enterRule(localctx, 80, self.RULE_setCommand) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 596 + self.state = 621 self.match(PartiQLParser.SET) - self.state = 597 + self.state = 622 self.setAssignment() - self.state = 602 + self.state = 627 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 598 + self.state = 623 self.match(PartiQLParser.COMMA) - self.state = 599 + self.state = 624 self.setAssignment() - self.state = 604 + self.state = 629 self._errHandler.sync(self) _la = self._input.LA(1) @@ -4819,14 +4955,14 @@ def accept(self, visitor:ParseTreeVisitor): def setAssignment(self): localctx = PartiQLParser.SetAssignmentContext(self, self._ctx, self.state) - self.enterRule(localctx, 80, self.RULE_setAssignment) + self.enterRule(localctx, 82, self.RULE_setAssignment) try: self.enterOuterAlt(localctx, 1) - self.state = 605 + self.state = 630 self.pathSimple() - self.state = 606 + self.state = 631 self.match(PartiQLParser.EQ) - self.state = 607 + self.state = 632 self.expr() except RecognitionException as re: localctx.exception = re @@ -4882,27 +5018,27 @@ def accept(self, visitor:ParseTreeVisitor): def deleteCommand(self): localctx = PartiQLParser.DeleteCommandContext(self, self._ctx, self.state) - self.enterRule(localctx, 82, self.RULE_deleteCommand) + self.enterRule(localctx, 84, self.RULE_deleteCommand) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 609 + self.state = 634 self.match(PartiQLParser.DELETE) - self.state = 610 + self.state = 635 self.fromClauseSimple() - self.state = 612 + self.state = 637 self._errHandler.sync(self) _la = self._input.LA(1) if _la==225: - self.state = 611 + self.state = 636 self.whereClause() - self.state = 615 + self.state = 640 self._errHandler.sync(self) _la = self._input.LA(1) if _la==246: - self.state = 614 + self.state = 639 self.returningClause() @@ -4961,23 +5097,23 @@ def accept(self, visitor:ParseTreeVisitor): def returningClause(self): localctx = PartiQLParser.ReturningClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 84, self.RULE_returningClause) + self.enterRule(localctx, 86, self.RULE_returningClause) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 617 + self.state = 642 self.match(PartiQLParser.RETURNING) - self.state = 618 + self.state = 643 self.returningColumn() - self.state = 623 + self.state = 648 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 619 + self.state = 644 self.match(PartiQLParser.COMMA) - self.state = 620 + self.state = 645 self.returningColumn() - self.state = 625 + self.state = 650 self._errHandler.sync(self) _la = self._input.LA(1) @@ -5042,15 +5178,15 @@ def accept(self, visitor:ParseTreeVisitor): def returningColumn(self): localctx = PartiQLParser.ReturningColumnContext(self, self._ctx, self.state) - self.enterRule(localctx, 86, self.RULE_returningColumn) + self.enterRule(localctx, 88, self.RULE_returningColumn) self._la = 0 # Token type try: - self.state = 632 + self.state = 657 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,49,self._ctx) + la_ = self._interp.adaptivePredict(self._input,53,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 626 + self.state = 651 localctx.status = self._input.LT(1) _la = self._input.LA(1) if not(_la==4 or _la==247): @@ -5058,7 +5194,7 @@ def returningColumn(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 627 + self.state = 652 localctx.age = self._input.LT(1) _la = self._input.LA(1) if not(_la==248 or _la==249): @@ -5066,13 +5202,13 @@ def returningColumn(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 628 + self.state = 653 self.match(PartiQLParser.ASTERISK) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 629 + self.state = 654 localctx.status = self._input.LT(1) _la = self._input.LA(1) if not(_la==4 or _la==247): @@ -5080,7 +5216,7 @@ def returningColumn(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 630 + self.state = 655 localctx.age = self._input.LT(1) _la = self._input.LA(1) if not(_la==248 or _la==249): @@ -5088,7 +5224,7 @@ def returningColumn(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 631 + self.state = 656 localctx.col = self.expr() pass @@ -5189,40 +5325,40 @@ def accept(self, visitor:ParseTreeVisitor): def fromClauseSimple(self): localctx = PartiQLParser.FromClauseSimpleContext(self, self._ctx, self.state) - self.enterRule(localctx, 88, self.RULE_fromClauseSimple) + self.enterRule(localctx, 90, self.RULE_fromClauseSimple) self._la = 0 # Token type try: - self.state = 649 + self.state = 674 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,53,self._ctx) + la_ = self._interp.adaptivePredict(self._input,57,self._ctx) if la_ == 1: localctx = PartiQLParser.FromClauseSimpleExplicitContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 634 + self.state = 659 self.match(PartiQLParser.FROM) - self.state = 635 + self.state = 660 self.pathSimple() - self.state = 637 + self.state = 662 self._errHandler.sync(self) _la = self._input.LA(1) if _la==10: - self.state = 636 + self.state = 661 self.asIdent() - self.state = 640 + self.state = 665 self._errHandler.sync(self) _la = self._input.LA(1) if _la==13: - self.state = 639 + self.state = 664 self.atIdent() - self.state = 643 + self.state = 668 self._errHandler.sync(self) _la = self._input.LA(1) if _la==20: - self.state = 642 + self.state = 667 self.byIdent() @@ -5231,11 +5367,11 @@ def fromClauseSimple(self): elif la_ == 2: localctx = PartiQLParser.FromClauseSimpleImplicitContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 645 + self.state = 670 self.match(PartiQLParser.FROM) - self.state = 646 + self.state = 671 self.pathSimple() - self.state = 647 + self.state = 672 self.symbolPrimitive() pass @@ -5287,12 +5423,12 @@ def accept(self, visitor:ParseTreeVisitor): def whereClause(self): localctx = PartiQLParser.WhereClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 90, self.RULE_whereClause) + self.enterRule(localctx, 92, self.RULE_whereClause) try: self.enterOuterAlt(localctx, 1) - self.state = 651 + self.state = 676 self.match(PartiQLParser.WHERE) - self.state = 652 + self.state = 677 localctx.arg = self.expr() except RecognitionException as re: localctx.exception = re @@ -5449,75 +5585,75 @@ def accept(self, visitor:ParseTreeVisitor): def selectClause(self): localctx = PartiQLParser.SelectClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 92, self.RULE_selectClause) + self.enterRule(localctx, 94, self.RULE_selectClause) self._la = 0 # Token type try: - self.state = 675 + self.state = 700 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,57,self._ctx) + la_ = self._interp.adaptivePredict(self._input,61,self._ctx) if la_ == 1: localctx = PartiQLParser.SelectAllContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 654 + self.state = 679 self.match(PartiQLParser.SELECT) - self.state = 656 + self.state = 681 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==67: - self.state = 655 + self.state = 680 self.setQuantifierStrategy() - self.state = 658 + self.state = 683 self.match(PartiQLParser.ASTERISK) pass elif la_ == 2: localctx = PartiQLParser.SelectItemsContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 659 + self.state = 684 self.match(PartiQLParser.SELECT) - self.state = 661 + self.state = 686 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==67: - self.state = 660 + self.state = 685 self.setQuantifierStrategy() - self.state = 663 + self.state = 688 self.projectionItems() pass elif la_ == 3: localctx = PartiQLParser.SelectValueContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 664 + self.state = 689 self.match(PartiQLParser.SELECT) - self.state = 666 + self.state = 691 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==67: - self.state = 665 + self.state = 690 self.setQuantifierStrategy() - self.state = 668 + self.state = 693 self.match(PartiQLParser.VALUE) - self.state = 669 + self.state = 694 self.expr() pass elif la_ == 4: localctx = PartiQLParser.SelectPivotContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 670 + self.state = 695 self.match(PartiQLParser.PIVOT) - self.state = 671 + self.state = 696 localctx.pivot = self.expr() - self.state = 672 + self.state = 697 self.match(PartiQLParser.AT) - self.state = 673 + self.state = 698 localctx.at = self.expr() pass @@ -5574,21 +5710,21 @@ def accept(self, visitor:ParseTreeVisitor): def projectionItems(self): localctx = PartiQLParser.ProjectionItemsContext(self, self._ctx, self.state) - self.enterRule(localctx, 94, self.RULE_projectionItems) + self.enterRule(localctx, 96, self.RULE_projectionItems) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 677 + self.state = 702 self.projectionItem() - self.state = 682 + self.state = 707 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 678 + self.state = 703 self.match(PartiQLParser.COMMA) - self.state = 679 + self.state = 704 self.projectionItem() - self.state = 684 + self.state = 709 self._errHandler.sync(self) _la = self._input.LA(1) @@ -5642,25 +5778,25 @@ def accept(self, visitor:ParseTreeVisitor): def projectionItem(self): localctx = PartiQLParser.ProjectionItemContext(self, self._ctx, self.state) - self.enterRule(localctx, 96, self.RULE_projectionItem) + self.enterRule(localctx, 98, self.RULE_projectionItem) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 685 + self.state = 710 self.expr() - self.state = 690 + self.state = 715 self._errHandler.sync(self) _la = self._input.LA(1) if _la==10 or _la==303 or _la==304: - self.state = 687 + self.state = 712 self._errHandler.sync(self) _la = self._input.LA(1) if _la==10: - self.state = 686 + self.state = 711 self.match(PartiQLParser.AS) - self.state = 689 + self.state = 714 self.symbolPrimitive() @@ -5709,11 +5845,11 @@ def accept(self, visitor:ParseTreeVisitor): def setQuantifierStrategy(self): localctx = PartiQLParser.SetQuantifierStrategyContext(self, self._ctx, self.state) - self.enterRule(localctx, 98, self.RULE_setQuantifierStrategy) + self.enterRule(localctx, 100, self.RULE_setQuantifierStrategy) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 692 + self.state = 717 _la = self._input.LA(1) if not(_la==4 or _la==67): self._errHandler.recoverInline(self) @@ -5775,25 +5911,25 @@ def accept(self, visitor:ParseTreeVisitor): def letClause(self): localctx = PartiQLParser.LetClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 100, self.RULE_letClause) + self.enterRule(localctx, 102, self.RULE_letClause) try: self.enterOuterAlt(localctx, 1) - self.state = 694 + self.state = 719 self.match(PartiQLParser.LET) - self.state = 695 + self.state = 720 self.letBinding() - self.state = 700 + self.state = 725 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,61,self._ctx) + _alt = self._interp.adaptivePredict(self._input,65,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 696 + self.state = 721 self.match(PartiQLParser.COMMA) - self.state = 697 + self.state = 722 self.letBinding() - self.state = 702 + self.state = 727 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,61,self._ctx) + _alt = self._interp.adaptivePredict(self._input,65,self._ctx) except RecognitionException as re: localctx.exception = re @@ -5845,14 +5981,14 @@ def accept(self, visitor:ParseTreeVisitor): def letBinding(self): localctx = PartiQLParser.LetBindingContext(self, self._ctx, self.state) - self.enterRule(localctx, 102, self.RULE_letBinding) + self.enterRule(localctx, 104, self.RULE_letBinding) try: self.enterOuterAlt(localctx, 1) - self.state = 703 + self.state = 728 self.expr() - self.state = 704 + self.state = 729 self.match(PartiQLParser.AS) - self.state = 705 + self.state = 730 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -5912,27 +6048,27 @@ def accept(self, visitor:ParseTreeVisitor): def orderByClause(self): localctx = PartiQLParser.OrderByClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 104, self.RULE_orderByClause) + self.enterRule(localctx, 106, self.RULE_orderByClause) try: self.enterOuterAlt(localctx, 1) - self.state = 707 + self.state = 732 self.match(PartiQLParser.ORDER) - self.state = 708 + self.state = 733 self.match(PartiQLParser.BY) - self.state = 709 + self.state = 734 self.orderSortSpec() - self.state = 714 + self.state = 739 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,62,self._ctx) + _alt = self._interp.adaptivePredict(self._input,66,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 710 + self.state = 735 self.match(PartiQLParser.COMMA) - self.state = 711 + self.state = 736 self.orderSortSpec() - self.state = 716 + self.state = 741 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,62,self._ctx) + _alt = self._interp.adaptivePredict(self._input,66,self._ctx) except RecognitionException as re: localctx.exception = re @@ -5994,17 +6130,17 @@ def accept(self, visitor:ParseTreeVisitor): def orderSortSpec(self): localctx = PartiQLParser.OrderSortSpecContext(self, self._ctx, self.state) - self.enterRule(localctx, 106, self.RULE_orderSortSpec) + self.enterRule(localctx, 108, self.RULE_orderSortSpec) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 717 + self.state = 742 self.expr() - self.state = 719 + self.state = 744 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,63,self._ctx) + la_ = self._interp.adaptivePredict(self._input,67,self._ctx) if la_ == 1: - self.state = 718 + self.state = 743 localctx.dir_ = self._input.LT(1) _la = self._input.LA(1) if not(_la==11 or _la==62): @@ -6014,13 +6150,13 @@ def orderSortSpec(self): self.consume() - self.state = 723 + self.state = 748 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,64,self._ctx) + la_ = self._interp.adaptivePredict(self._input,68,self._ctx) if la_ == 1: - self.state = 721 + self.state = 746 self.match(PartiQLParser.NULLS) - self.state = 722 + self.state = 747 localctx.nulls = self._input.LT(1) _la = self._input.LA(1) if not(_la==90 or _la==123): @@ -6095,42 +6231,42 @@ def accept(self, visitor:ParseTreeVisitor): def groupClause(self): localctx = PartiQLParser.GroupClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 108, self.RULE_groupClause) + self.enterRule(localctx, 110, self.RULE_groupClause) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 725 + self.state = 750 self.match(PartiQLParser.GROUP) - self.state = 727 + self.state = 752 self._errHandler.sync(self) _la = self._input.LA(1) if _la==158: - self.state = 726 + self.state = 751 self.match(PartiQLParser.PARTIAL) - self.state = 729 + self.state = 754 self.match(PartiQLParser.BY) - self.state = 730 + self.state = 755 self.groupKey() - self.state = 735 + self.state = 760 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,66,self._ctx) + _alt = self._interp.adaptivePredict(self._input,70,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 731 + self.state = 756 self.match(PartiQLParser.COMMA) - self.state = 732 + self.state = 757 self.groupKey() - self.state = 737 + self.state = 762 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,66,self._ctx) + _alt = self._interp.adaptivePredict(self._input,70,self._ctx) - self.state = 739 + self.state = 764 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,67,self._ctx) + la_ = self._interp.adaptivePredict(self._input,71,self._ctx) if la_ == 1: - self.state = 738 + self.state = 763 self.groupAlias() @@ -6183,14 +6319,14 @@ def accept(self, visitor:ParseTreeVisitor): def groupAlias(self): localctx = PartiQLParser.GroupAliasContext(self, self._ctx, self.state) - self.enterRule(localctx, 110, self.RULE_groupAlias) + self.enterRule(localctx, 112, self.RULE_groupAlias) try: self.enterOuterAlt(localctx, 1) - self.state = 741 + self.state = 766 self.match(PartiQLParser.GROUP) - self.state = 742 + self.state = 767 self.match(PartiQLParser.AS) - self.state = 743 + self.state = 768 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -6243,18 +6379,18 @@ def accept(self, visitor:ParseTreeVisitor): def groupKey(self): localctx = PartiQLParser.GroupKeyContext(self, self._ctx, self.state) - self.enterRule(localctx, 112, self.RULE_groupKey) + self.enterRule(localctx, 114, self.RULE_groupKey) try: self.enterOuterAlt(localctx, 1) - self.state = 745 + self.state = 770 localctx.key = self.exprSelect() - self.state = 748 + self.state = 773 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,68,self._ctx) + la_ = self._interp.adaptivePredict(self._input,72,self._ctx) if la_ == 1: - self.state = 746 + self.state = 771 self.match(PartiQLParser.AS) - self.state = 747 + self.state = 772 self.symbolPrimitive() @@ -6314,31 +6450,31 @@ def accept(self, visitor:ParseTreeVisitor): def over(self): localctx = PartiQLParser.OverContext(self, self._ctx, self.state) - self.enterRule(localctx, 114, self.RULE_over) + self.enterRule(localctx, 116, self.RULE_over) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 750 + self.state = 775 self.match(PartiQLParser.OVER) - self.state = 751 + self.state = 776 self.match(PartiQLParser.PAREN_LEFT) - self.state = 753 + self.state = 778 self._errHandler.sync(self) _la = self._input.LA(1) if _la==233: - self.state = 752 + self.state = 777 self.windowPartitionList() - self.state = 756 + self.state = 781 self._errHandler.sync(self) _la = self._input.LA(1) if _la==152: - self.state = 755 + self.state = 780 self.windowSortSpecList() - self.state = 758 + self.state = 783 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -6398,25 +6534,25 @@ def accept(self, visitor:ParseTreeVisitor): def windowPartitionList(self): localctx = PartiQLParser.WindowPartitionListContext(self, self._ctx, self.state) - self.enterRule(localctx, 116, self.RULE_windowPartitionList) + self.enterRule(localctx, 118, self.RULE_windowPartitionList) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 760 + self.state = 785 self.match(PartiQLParser.PARTITION) - self.state = 761 + self.state = 786 self.match(PartiQLParser.BY) - self.state = 762 + self.state = 787 self.expr() - self.state = 767 + self.state = 792 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 763 + self.state = 788 self.match(PartiQLParser.COMMA) - self.state = 764 + self.state = 789 self.expr() - self.state = 769 + self.state = 794 self._errHandler.sync(self) _la = self._input.LA(1) @@ -6478,25 +6614,25 @@ def accept(self, visitor:ParseTreeVisitor): def windowSortSpecList(self): localctx = PartiQLParser.WindowSortSpecListContext(self, self._ctx, self.state) - self.enterRule(localctx, 118, self.RULE_windowSortSpecList) + self.enterRule(localctx, 120, self.RULE_windowSortSpecList) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 770 + self.state = 795 self.match(PartiQLParser.ORDER) - self.state = 771 + self.state = 796 self.match(PartiQLParser.BY) - self.state = 772 + self.state = 797 self.orderSortSpec() - self.state = 777 + self.state = 802 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 773 + self.state = 798 self.match(PartiQLParser.COMMA) - self.state = 774 + self.state = 799 self.orderSortSpec() - self.state = 779 + self.state = 804 self._errHandler.sync(self) _la = self._input.LA(1) @@ -6547,12 +6683,12 @@ def accept(self, visitor:ParseTreeVisitor): def havingClause(self): localctx = PartiQLParser.HavingClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 120, self.RULE_havingClause) + self.enterRule(localctx, 122, self.RULE_havingClause) try: self.enterOuterAlt(localctx, 1) - self.state = 780 + self.state = 805 self.match(PartiQLParser.HAVING) - self.state = 781 + self.state = 806 localctx.arg = self.exprSelect() except RecognitionException as re: localctx.exception = re @@ -6609,23 +6745,23 @@ def accept(self, visitor:ParseTreeVisitor): def excludeClause(self): localctx = PartiQLParser.ExcludeClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 122, self.RULE_excludeClause) + self.enterRule(localctx, 124, self.RULE_excludeClause) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 783 + self.state = 808 self.match(PartiQLParser.EXCLUDE) - self.state = 784 + self.state = 809 self.excludeExpr() - self.state = 789 + self.state = 814 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 785 + self.state = 810 self.match(PartiQLParser.COMMA) - self.state = 786 + self.state = 811 self.excludeExpr() - self.state = 791 + self.state = 816 self._errHandler.sync(self) _la = self._input.LA(1) @@ -6679,19 +6815,19 @@ def accept(self, visitor:ParseTreeVisitor): def excludeExpr(self): localctx = PartiQLParser.ExcludeExprContext(self, self._ctx, self.state) - self.enterRule(localctx, 124, self.RULE_excludeExpr) + self.enterRule(localctx, 126, self.RULE_excludeExpr) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 792 + self.state = 817 self.symbolPrimitive() - self.state = 794 + self.state = 819 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 793 + self.state = 818 self.excludeExprSteps() - self.state = 796 + self.state = 821 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==290 or _la==299): @@ -6866,59 +7002,59 @@ def accept(self, visitor:ParseTreeVisitor): def excludeExprSteps(self): localctx = PartiQLParser.ExcludeExprStepsContext(self, self._ctx, self.state) - self.enterRule(localctx, 126, self.RULE_excludeExprSteps) + self.enterRule(localctx, 128, self.RULE_excludeExprSteps) try: - self.state = 811 + self.state = 836 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,75,self._ctx) + la_ = self._interp.adaptivePredict(self._input,79,self._ctx) if la_ == 1: localctx = PartiQLParser.ExcludeExprTupleAttrContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 798 + self.state = 823 self.match(PartiQLParser.PERIOD) - self.state = 799 + self.state = 824 self.symbolPrimitive() pass elif la_ == 2: localctx = PartiQLParser.ExcludeExprCollectionAttrContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 800 + self.state = 825 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 801 + self.state = 826 localctx.attr = self.match(PartiQLParser.LITERAL_STRING) - self.state = 802 + self.state = 827 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 3: localctx = PartiQLParser.ExcludeExprCollectionIndexContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 803 + self.state = 828 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 804 + self.state = 829 localctx.index = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 805 + self.state = 830 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 4: localctx = PartiQLParser.ExcludeExprCollectionWildcardContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 806 + self.state = 831 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 807 + self.state = 832 self.match(PartiQLParser.ASTERISK) - self.state = 808 + self.state = 833 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 5: localctx = PartiQLParser.ExcludeExprTupleWildcardContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 809 + self.state = 834 self.match(PartiQLParser.PERIOD) - self.state = 810 + self.state = 835 self.match(PartiQLParser.ASTERISK) pass @@ -6969,12 +7105,12 @@ def accept(self, visitor:ParseTreeVisitor): def fromClause(self): localctx = PartiQLParser.FromClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 128, self.RULE_fromClause) + self.enterRule(localctx, 130, self.RULE_fromClause) try: self.enterOuterAlt(localctx, 1) - self.state = 813 + self.state = 838 self.match(PartiQLParser.FROM) - self.state = 814 + self.state = 839 self.tableReference(0) except RecognitionException as re: localctx.exception = re @@ -7023,12 +7159,12 @@ def accept(self, visitor:ParseTreeVisitor): def whereClauseSelect(self): localctx = PartiQLParser.WhereClauseSelectContext(self, self._ctx, self.state) - self.enterRule(localctx, 130, self.RULE_whereClauseSelect) + self.enterRule(localctx, 132, self.RULE_whereClauseSelect) try: self.enterOuterAlt(localctx, 1) - self.state = 816 + self.state = 841 self.match(PartiQLParser.WHERE) - self.state = 817 + self.state = 842 localctx.arg = self.exprSelect() except RecognitionException as re: localctx.exception = re @@ -7077,12 +7213,12 @@ def accept(self, visitor:ParseTreeVisitor): def offsetByClause(self): localctx = PartiQLParser.OffsetByClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 132, self.RULE_offsetByClause) + self.enterRule(localctx, 134, self.RULE_offsetByClause) try: self.enterOuterAlt(localctx, 1) - self.state = 819 + self.state = 844 self.match(PartiQLParser.OFFSET) - self.state = 820 + self.state = 845 localctx.arg = self.exprSelect() except RecognitionException as re: localctx.exception = re @@ -7131,12 +7267,12 @@ def accept(self, visitor:ParseTreeVisitor): def limitClause(self): localctx = PartiQLParser.LimitClauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 134, self.RULE_limitClause) + self.enterRule(localctx, 136, self.RULE_limitClause) try: self.enterOuterAlt(localctx, 1) - self.state = 822 + self.state = 847 self.match(PartiQLParser.LIMIT) - self.state = 823 + self.state = 848 localctx.arg = self.exprSelect() except RecognitionException as re: localctx.exception = re @@ -7186,18 +7322,18 @@ def accept(self, visitor:ParseTreeVisitor): def gpmlPattern(self): localctx = PartiQLParser.GpmlPatternContext(self, self._ctx, self.state) - self.enterRule(localctx, 136, self.RULE_gpmlPattern) + self.enterRule(localctx, 138, self.RULE_gpmlPattern) try: self.enterOuterAlt(localctx, 1) - self.state = 826 + self.state = 851 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,76,self._ctx) + la_ = self._interp.adaptivePredict(self._input,80,self._ctx) if la_ == 1: - self.state = 825 + self.state = 850 localctx.selector = self.matchSelector() - self.state = 828 + self.state = 853 self.matchPattern() except RecognitionException as re: localctx.exception = re @@ -7256,29 +7392,29 @@ def accept(self, visitor:ParseTreeVisitor): def gpmlPatternList(self): localctx = PartiQLParser.GpmlPatternListContext(self, self._ctx, self.state) - self.enterRule(localctx, 138, self.RULE_gpmlPatternList) + self.enterRule(localctx, 140, self.RULE_gpmlPatternList) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 831 + self.state = 856 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==8 or _la==186: - self.state = 830 + self.state = 855 localctx.selector = self.matchSelector() - self.state = 833 + self.state = 858 self.matchPattern() - self.state = 838 + self.state = 863 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 834 + self.state = 859 self.match(PartiQLParser.COMMA) - self.state = 835 + self.state = 860 self.matchPattern() - self.state = 840 + self.state = 865 self._errHandler.sync(self) _la = self._input.LA(1) @@ -7338,35 +7474,35 @@ def accept(self, visitor:ParseTreeVisitor): def matchPattern(self): localctx = PartiQLParser.MatchPatternContext(self, self._ctx, self.state) - self.enterRule(localctx, 140, self.RULE_matchPattern) + self.enterRule(localctx, 142, self.RULE_matchPattern) try: self.enterOuterAlt(localctx, 1) - self.state = 842 + self.state = 867 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,79,self._ctx) + la_ = self._interp.adaptivePredict(self._input,83,self._ctx) if la_ == 1: - self.state = 841 + self.state = 866 localctx.restrictor = self.patternRestrictor() - self.state = 845 + self.state = 870 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,80,self._ctx) + la_ = self._interp.adaptivePredict(self._input,84,self._ctx) if la_ == 1: - self.state = 844 + self.state = 869 localctx.variable = self.patternPathVariable() - self.state = 850 + self.state = 875 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,81,self._ctx) + _alt = self._interp.adaptivePredict(self._input,85,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 847 + self.state = 872 self.graphPart() - self.state = 852 + self.state = 877 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,81,self._ctx) + _alt = self._interp.adaptivePredict(self._input,85,self._ctx) except RecognitionException as re: localctx.exception = re @@ -7419,26 +7555,26 @@ def accept(self, visitor:ParseTreeVisitor): def graphPart(self): localctx = PartiQLParser.GraphPartContext(self, self._ctx, self.state) - self.enterRule(localctx, 142, self.RULE_graphPart) + self.enterRule(localctx, 144, self.RULE_graphPart) try: - self.state = 856 + self.state = 881 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,82,self._ctx) + la_ = self._interp.adaptivePredict(self._input,86,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 853 + self.state = 878 self.node() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 854 + self.state = 879 self.edge() pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 855 + self.state = 880 self.pattern() pass @@ -7558,16 +7694,16 @@ def accept(self, visitor:ParseTreeVisitor): def matchSelector(self): localctx = PartiQLParser.MatchSelectorContext(self, self._ctx, self.state) - self.enterRule(localctx, 144, self.RULE_matchSelector) + self.enterRule(localctx, 146, self.RULE_matchSelector) self._la = 0 # Token type try: - self.state = 869 + self.state = 894 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,85,self._ctx) + la_ = self._interp.adaptivePredict(self._input,89,self._ctx) if la_ == 1: localctx = PartiQLParser.SelectorBasicContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 858 + self.state = 883 localctx.mod = self._input.LT(1) _la = self._input.LA(1) if not(_la==4 or _la==8): @@ -7575,20 +7711,20 @@ def matchSelector(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 859 + self.state = 884 self.match(PartiQLParser.SHORTEST) pass elif la_ == 2: localctx = PartiQLParser.SelectorAnyContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 860 + self.state = 885 self.match(PartiQLParser.ANY) - self.state = 862 + self.state = 887 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,83,self._ctx) + la_ = self._interp.adaptivePredict(self._input,87,self._ctx) if la_ == 1: - self.state = 861 + self.state = 886 localctx.k = self.match(PartiQLParser.LITERAL_INTEGER) @@ -7597,15 +7733,15 @@ def matchSelector(self): elif la_ == 3: localctx = PartiQLParser.SelectorShortestContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 864 + self.state = 889 self.match(PartiQLParser.SHORTEST) - self.state = 865 + self.state = 890 localctx.k = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 867 + self.state = 892 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,84,self._ctx) + la_ = self._interp.adaptivePredict(self._input,88,self._ctx) if la_ == 1: - self.state = 866 + self.state = 891 self.match(PartiQLParser.GROUP) @@ -7658,12 +7794,12 @@ def accept(self, visitor:ParseTreeVisitor): def patternPathVariable(self): localctx = PartiQLParser.PatternPathVariableContext(self, self._ctx, self.state) - self.enterRule(localctx, 146, self.RULE_patternPathVariable) + self.enterRule(localctx, 148, self.RULE_patternPathVariable) try: self.enterOuterAlt(localctx, 1) - self.state = 871 + self.state = 896 self.symbolPrimitive() - self.state = 872 + self.state = 897 self.match(PartiQLParser.EQ) except RecognitionException as re: localctx.exception = re @@ -7708,10 +7844,10 @@ def accept(self, visitor:ParseTreeVisitor): def patternRestrictor(self): localctx = PartiQLParser.PatternRestrictorContext(self, self._ctx, self.state) - self.enterRule(localctx, 148, self.RULE_patternRestrictor) + self.enterRule(localctx, 150, self.RULE_patternRestrictor) try: self.enterOuterAlt(localctx, 1) - self.state = 874 + self.state = 899 localctx.restrictor = self.match(PartiQLParser.IDENTIFIER) except RecognitionException as re: localctx.exception = re @@ -7773,39 +7909,39 @@ def accept(self, visitor:ParseTreeVisitor): def node(self): localctx = PartiQLParser.NodeContext(self, self._ctx, self.state) - self.enterRule(localctx, 150, self.RULE_node) + self.enterRule(localctx, 152, self.RULE_node) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 876 + self.state = 901 self.match(PartiQLParser.PAREN_LEFT) - self.state = 878 + self.state = 903 self._errHandler.sync(self) _la = self._input.LA(1) if _la==303 or _la==304: - self.state = 877 + self.state = 902 self.symbolPrimitive() - self.state = 882 + self.state = 907 self._errHandler.sync(self) _la = self._input.LA(1) if _la==296: - self.state = 880 + self.state = 905 self.match(PartiQLParser.COLON) - self.state = 881 + self.state = 906 self.labelSpec(0) - self.state = 885 + self.state = 910 self._errHandler.sync(self) _la = self._input.LA(1) if _la==225: - self.state = 884 + self.state = 909 self.whereClause() - self.state = 887 + self.state = 912 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -7895,21 +8031,21 @@ def accept(self, visitor:ParseTreeVisitor): def edge(self): localctx = PartiQLParser.EdgeContext(self, self._ctx, self.state) - self.enterRule(localctx, 152, self.RULE_edge) + self.enterRule(localctx, 154, self.RULE_edge) try: - self.state = 897 + self.state = 922 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,91,self._ctx) + la_ = self._interp.adaptivePredict(self._input,95,self._ctx) if la_ == 1: localctx = PartiQLParser.EdgeWithSpecContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 889 + self.state = 914 self.edgeWSpec() - self.state = 891 + self.state = 916 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,89,self._ctx) + la_ = self._interp.adaptivePredict(self._input,93,self._ctx) if la_ == 1: - self.state = 890 + self.state = 915 localctx.quantifier = self.patternQuantifier() @@ -7918,13 +8054,13 @@ def edge(self): elif la_ == 2: localctx = PartiQLParser.EdgeAbbreviatedContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 893 + self.state = 918 self.edgeAbbrev() - self.state = 895 + self.state = 920 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,90,self._ctx) + la_ = self._interp.adaptivePredict(self._input,94,self._ctx) if la_ == 1: - self.state = 894 + self.state = 919 localctx.quantifier = self.patternQuantifier() @@ -8009,110 +8145,110 @@ def accept(self, visitor:ParseTreeVisitor): def pattern(self): localctx = PartiQLParser.PatternContext(self, self._ctx, self.state) - self.enterRule(localctx, 154, self.RULE_pattern) + self.enterRule(localctx, 156, self.RULE_pattern) self._la = 0 # Token type try: - self.state = 937 + self.state = 962 self._errHandler.sync(self) token = self._input.LA(1) if token in [294]: self.enterOuterAlt(localctx, 1) - self.state = 899 + self.state = 924 self.match(PartiQLParser.PAREN_LEFT) - self.state = 901 + self.state = 926 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,92,self._ctx) + la_ = self._interp.adaptivePredict(self._input,96,self._ctx) if la_ == 1: - self.state = 900 + self.state = 925 localctx.restrictor = self.patternRestrictor() - self.state = 904 + self.state = 929 self._errHandler.sync(self) _la = self._input.LA(1) if _la==303 or _la==304: - self.state = 903 + self.state = 928 localctx.variable = self.patternPathVariable() - self.state = 907 + self.state = 932 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 906 + self.state = 931 self.graphPart() - self.state = 909 + self.state = 934 self._errHandler.sync(self) _la = self._input.LA(1) if not (((((_la - 272)) & ~0x3f) == 0 and ((1 << (_la - 272)) & 4472849) != 0)): break - self.state = 912 + self.state = 937 self._errHandler.sync(self) _la = self._input.LA(1) if _la==225: - self.state = 911 + self.state = 936 localctx.where = self.whereClause() - self.state = 914 + self.state = 939 self.match(PartiQLParser.PAREN_RIGHT) - self.state = 916 + self.state = 941 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,96,self._ctx) + la_ = self._interp.adaptivePredict(self._input,100,self._ctx) if la_ == 1: - self.state = 915 + self.state = 940 localctx.quantifier = self.patternQuantifier() pass elif token in [290]: self.enterOuterAlt(localctx, 2) - self.state = 918 + self.state = 943 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 920 + self.state = 945 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,97,self._ctx) + la_ = self._interp.adaptivePredict(self._input,101,self._ctx) if la_ == 1: - self.state = 919 + self.state = 944 localctx.restrictor = self.patternRestrictor() - self.state = 923 + self.state = 948 self._errHandler.sync(self) _la = self._input.LA(1) if _la==303 or _la==304: - self.state = 922 + self.state = 947 localctx.variable = self.patternPathVariable() - self.state = 926 + self.state = 951 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 925 + self.state = 950 self.graphPart() - self.state = 928 + self.state = 953 self._errHandler.sync(self) _la = self._input.LA(1) if not (((((_la - 272)) & ~0x3f) == 0 and ((1 << (_la - 272)) & 4472849) != 0)): break - self.state = 931 + self.state = 956 self._errHandler.sync(self) _la = self._input.LA(1) if _la==225: - self.state = 930 + self.state = 955 localctx.where = self.whereClause() - self.state = 933 + self.state = 958 self.match(PartiQLParser.BRACKET_RIGHT) - self.state = 935 + self.state = 960 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,101,self._ctx) + la_ = self._interp.adaptivePredict(self._input,105,self._ctx) if la_ == 1: - self.state = 934 + self.state = 959 localctx.quantifier = self.patternQuantifier() @@ -8183,15 +8319,15 @@ def accept(self, visitor:ParseTreeVisitor): def patternQuantifier(self): localctx = PartiQLParser.PatternQuantifierContext(self, self._ctx, self.state) - self.enterRule(localctx, 156, self.RULE_patternQuantifier) + self.enterRule(localctx, 158, self.RULE_patternQuantifier) self._la = 0 # Token type try: - self.state = 947 + self.state = 972 self._errHandler.sync(self) token = self._input.LA(1) if token in [271, 277]: self.enterOuterAlt(localctx, 1) - self.state = 939 + self.state = 964 localctx.quant = self._input.LT(1) _la = self._input.LA(1) if not(_la==271 or _la==277): @@ -8202,21 +8338,21 @@ def patternQuantifier(self): pass elif token in [292]: self.enterOuterAlt(localctx, 2) - self.state = 940 + self.state = 965 self.match(PartiQLParser.BRACE_LEFT) - self.state = 941 + self.state = 966 localctx.lower = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 942 + self.state = 967 self.match(PartiQLParser.COMMA) - self.state = 944 + self.state = 969 self._errHandler.sync(self) _la = self._input.LA(1) if _la==301: - self.state = 943 + self.state = 968 localctx.upper = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 946 + self.state = 971 self.match(PartiQLParser.BRACE_RIGHT) pass else: @@ -8474,97 +8610,97 @@ def accept(self, visitor:ParseTreeVisitor): def edgeWSpec(self): localctx = PartiQLParser.EdgeWSpecContext(self, self._ctx, self.state) - self.enterRule(localctx, 158, self.RULE_edgeWSpec) + self.enterRule(localctx, 160, self.RULE_edgeWSpec) try: - self.state = 983 + self.state = 1008 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,105,self._ctx) + la_ = self._interp.adaptivePredict(self._input,109,self._ctx) if la_ == 1: localctx = PartiQLParser.EdgeSpecRightContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 949 + self.state = 974 self.match(PartiQLParser.MINUS) - self.state = 950 + self.state = 975 self.edgeSpec() - self.state = 951 + self.state = 976 self.match(PartiQLParser.MINUS) - self.state = 952 + self.state = 977 self.match(PartiQLParser.ANGLE_RIGHT) pass elif la_ == 2: localctx = PartiQLParser.EdgeSpecUndirectedContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 954 + self.state = 979 self.match(PartiQLParser.TILDE) - self.state = 955 + self.state = 980 self.edgeSpec() - self.state = 956 + self.state = 981 self.match(PartiQLParser.TILDE) pass elif la_ == 3: localctx = PartiQLParser.EdgeSpecLeftContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 958 + self.state = 983 self.match(PartiQLParser.ANGLE_LEFT) - self.state = 959 + self.state = 984 self.match(PartiQLParser.MINUS) - self.state = 960 + self.state = 985 self.edgeSpec() - self.state = 961 + self.state = 986 self.match(PartiQLParser.MINUS) pass elif la_ == 4: localctx = PartiQLParser.EdgeSpecUndirectedRightContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 963 + self.state = 988 self.match(PartiQLParser.TILDE) - self.state = 964 + self.state = 989 self.edgeSpec() - self.state = 965 + self.state = 990 self.match(PartiQLParser.TILDE) - self.state = 966 + self.state = 991 self.match(PartiQLParser.ANGLE_RIGHT) pass elif la_ == 5: localctx = PartiQLParser.EdgeSpecUndirectedLeftContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 968 + self.state = 993 self.match(PartiQLParser.ANGLE_LEFT) - self.state = 969 + self.state = 994 self.match(PartiQLParser.TILDE) - self.state = 970 + self.state = 995 self.edgeSpec() - self.state = 971 + self.state = 996 self.match(PartiQLParser.TILDE) pass elif la_ == 6: localctx = PartiQLParser.EdgeSpecBidirectionalContext(self, localctx) self.enterOuterAlt(localctx, 6) - self.state = 973 + self.state = 998 self.match(PartiQLParser.ANGLE_LEFT) - self.state = 974 + self.state = 999 self.match(PartiQLParser.MINUS) - self.state = 975 + self.state = 1000 self.edgeSpec() - self.state = 976 + self.state = 1001 self.match(PartiQLParser.MINUS) - self.state = 977 + self.state = 1002 self.match(PartiQLParser.ANGLE_RIGHT) pass elif la_ == 7: localctx = PartiQLParser.EdgeSpecUndirectedBidirectionalContext(self, localctx) self.enterOuterAlt(localctx, 7) - self.state = 979 + self.state = 1004 self.match(PartiQLParser.MINUS) - self.state = 980 + self.state = 1005 self.edgeSpec() - self.state = 981 + self.state = 1006 self.match(PartiQLParser.MINUS) pass @@ -8629,39 +8765,39 @@ def accept(self, visitor:ParseTreeVisitor): def edgeSpec(self): localctx = PartiQLParser.EdgeSpecContext(self, self._ctx, self.state) - self.enterRule(localctx, 160, self.RULE_edgeSpec) + self.enterRule(localctx, 162, self.RULE_edgeSpec) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 985 + self.state = 1010 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 987 + self.state = 1012 self._errHandler.sync(self) _la = self._input.LA(1) if _la==303 or _la==304: - self.state = 986 + self.state = 1011 self.symbolPrimitive() - self.state = 991 + self.state = 1016 self._errHandler.sync(self) _la = self._input.LA(1) if _la==296: - self.state = 989 + self.state = 1014 self.match(PartiQLParser.COLON) - self.state = 990 + self.state = 1015 self.labelSpec(0) - self.state = 994 + self.state = 1019 self._errHandler.sync(self) _la = self._input.LA(1) if _la==225: - self.state = 993 + self.state = 1018 self.whereClause() - self.state = 996 + self.state = 1021 self.match(PartiQLParser.BRACKET_RIGHT) except RecognitionException as re: localctx.exception = re @@ -8749,20 +8885,20 @@ def labelSpec(self, _p:int=0): _parentState = self.state localctx = PartiQLParser.LabelSpecContext(self, self._ctx, _parentState) _prevctx = localctx - _startState = 162 - self.enterRecursionRule(localctx, 162, self.RULE_labelSpec, _p) + _startState = 164 + self.enterRecursionRule(localctx, 164, self.RULE_labelSpec, _p) try: self.enterOuterAlt(localctx, 1) localctx = PartiQLParser.LabelSpecTermContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 999 + self.state = 1024 self.labelTerm(0) self._ctx.stop = self._input.LT(-1) - self.state = 1006 + self.state = 1031 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,109,self._ctx) + _alt = self._interp.adaptivePredict(self._input,113,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: @@ -8770,17 +8906,17 @@ def labelSpec(self, _p:int=0): _prevctx = localctx localctx = PartiQLParser.LabelSpecOrContext(self, PartiQLParser.LabelSpecContext(self, _parentctx, _parentState)) self.pushNewRecursionContext(localctx, _startState, self.RULE_labelSpec) - self.state = 1001 + self.state = 1026 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1002 + self.state = 1027 self.match(PartiQLParser.VERTBAR) - self.state = 1003 + self.state = 1028 self.labelTerm(0) - self.state = 1008 + self.state = 1033 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,109,self._ctx) + _alt = self._interp.adaptivePredict(self._input,113,self._ctx) except RecognitionException as re: localctx.exception = re @@ -8868,20 +9004,20 @@ def labelTerm(self, _p:int=0): _parentState = self.state localctx = PartiQLParser.LabelTermContext(self, self._ctx, _parentState) _prevctx = localctx - _startState = 164 - self.enterRecursionRule(localctx, 164, self.RULE_labelTerm, _p) + _startState = 166 + self.enterRecursionRule(localctx, 166, self.RULE_labelTerm, _p) try: self.enterOuterAlt(localctx, 1) localctx = PartiQLParser.LabelTermFactorContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1010 + self.state = 1035 self.labelFactor() self._ctx.stop = self._input.LT(-1) - self.state = 1017 + self.state = 1042 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,110,self._ctx) + _alt = self._interp.adaptivePredict(self._input,114,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: @@ -8889,17 +9025,17 @@ def labelTerm(self, _p:int=0): _prevctx = localctx localctx = PartiQLParser.LabelTermAndContext(self, PartiQLParser.LabelTermContext(self, _parentctx, _parentState)) self.pushNewRecursionContext(localctx, _startState, self.RULE_labelTerm) - self.state = 1012 + self.state = 1037 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1013 + self.state = 1038 self.match(PartiQLParser.AMPERSAND) - self.state = 1014 + self.state = 1039 self.labelFactor() - self.state = 1019 + self.state = 1044 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,110,self._ctx) + _alt = self._interp.adaptivePredict(self._input,114,self._ctx) except RecognitionException as re: localctx.exception = re @@ -8983,23 +9119,23 @@ def accept(self, visitor:ParseTreeVisitor): def labelFactor(self): localctx = PartiQLParser.LabelFactorContext(self, self._ctx, self.state) - self.enterRule(localctx, 166, self.RULE_labelFactor) + self.enterRule(localctx, 168, self.RULE_labelFactor) try: - self.state = 1023 + self.state = 1048 self._errHandler.sync(self) token = self._input.LA(1) if token in [280]: localctx = PartiQLParser.LabelFactorNotContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1020 + self.state = 1045 self.match(PartiQLParser.BANG) - self.state = 1021 + self.state = 1046 self.labelPrimary() pass elif token in [274, 294, 303, 304]: localctx = PartiQLParser.LabelFactorPrimaryContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1022 + self.state = 1047 self.labelPrimary() pass else: @@ -9113,31 +9249,31 @@ def accept(self, visitor:ParseTreeVisitor): def labelPrimary(self): localctx = PartiQLParser.LabelPrimaryContext(self, self._ctx, self.state) - self.enterRule(localctx, 168, self.RULE_labelPrimary) + self.enterRule(localctx, 170, self.RULE_labelPrimary) try: - self.state = 1031 + self.state = 1056 self._errHandler.sync(self) token = self._input.LA(1) if token in [303, 304]: localctx = PartiQLParser.LabelPrimaryNameContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1025 + self.state = 1050 self.symbolPrimitive() pass elif token in [274]: localctx = PartiQLParser.LabelPrimaryWildContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1026 + self.state = 1051 self.match(PartiQLParser.PERCENT) pass elif token in [294]: localctx = PartiQLParser.LabelPrimaryParenContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1027 + self.state = 1052 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1028 + self.state = 1053 self.labelSpec(0) - self.state = 1029 + self.state = 1054 self.match(PartiQLParser.PAREN_RIGHT) pass else: @@ -9194,51 +9330,51 @@ def accept(self, visitor:ParseTreeVisitor): def edgeAbbrev(self): localctx = PartiQLParser.EdgeAbbrevContext(self, self._ctx, self.state) - self.enterRule(localctx, 170, self.RULE_edgeAbbrev) + self.enterRule(localctx, 172, self.RULE_edgeAbbrev) self._la = 0 # Token type try: - self.state = 1045 + self.state = 1070 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,115,self._ctx) + la_ = self._interp.adaptivePredict(self._input,119,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 1033 + self.state = 1058 self.match(PartiQLParser.TILDE) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 1034 + self.state = 1059 self.match(PartiQLParser.TILDE) - self.state = 1035 + self.state = 1060 self.match(PartiQLParser.ANGLE_RIGHT) pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 1036 + self.state = 1061 self.match(PartiQLParser.ANGLE_LEFT) - self.state = 1037 + self.state = 1062 self.match(PartiQLParser.TILDE) pass elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 1039 + self.state = 1064 self._errHandler.sync(self) _la = self._input.LA(1) if _la==286: - self.state = 1038 + self.state = 1063 self.match(PartiQLParser.ANGLE_LEFT) - self.state = 1041 + self.state = 1066 self.match(PartiQLParser.MINUS) - self.state = 1043 + self.state = 1068 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,114,self._ctx) + la_ = self._interp.adaptivePredict(self._input,118,self._ctx) if la_ == 1: - self.state = 1042 + self.state = 1067 self.match(PartiQLParser.ANGLE_RIGHT) @@ -9407,20 +9543,20 @@ def tableReference(self, _p:int=0): _parentState = self.state localctx = PartiQLParser.TableReferenceContext(self, self._ctx, _parentState) _prevctx = localctx - _startState = 172 - self.enterRecursionRule(localctx, 172, self.RULE_tableReference, _p) + _startState = 174 + self.enterRecursionRule(localctx, 174, self.RULE_tableReference, _p) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1053 + self.state = 1078 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,116,self._ctx) + la_ = self._interp.adaptivePredict(self._input,120,self._ctx) if la_ == 1: localctx = PartiQLParser.TableRefBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1048 + self.state = 1073 self.tableNonJoin() pass @@ -9428,48 +9564,48 @@ def tableReference(self, _p:int=0): localctx = PartiQLParser.TableWrappedContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1049 + self.state = 1074 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1050 + self.state = 1075 self.tableReference(0) - self.state = 1051 + self.state = 1076 self.match(PartiQLParser.PAREN_RIGHT) pass self._ctx.stop = self._input.LT(-1) - self.state = 1075 + self.state = 1100 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,120,self._ctx) + _alt = self._interp.adaptivePredict(self._input,124,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 1073 + self.state = 1098 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,119,self._ctx) + la_ = self._interp.adaptivePredict(self._input,123,self._ctx) if la_ == 1: localctx = PartiQLParser.TableCrossJoinContext(self, PartiQLParser.TableReferenceContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_tableReference) - self.state = 1055 + self.state = 1080 if not self.precpred(self._ctx, 5): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") - self.state = 1057 + self.state = 1082 self._errHandler.sync(self) _la = self._input.LA(1) if ((((_la - 96)) & ~0x3f) == 0 and ((1 << (_la - 96)) & 144115188612734977) != 0) or _la==176: - self.state = 1056 + self.state = 1081 self.joinType() - self.state = 1059 + self.state = 1084 self.match(PartiQLParser.CROSS) - self.state = 1060 + self.state = 1085 self.match(PartiQLParser.JOIN) - self.state = 1061 + self.state = 1086 localctx.rhs = self.joinRhs() pass @@ -9477,13 +9613,13 @@ def tableReference(self, _p:int=0): localctx = PartiQLParser.TableCrossJoinContext(self, PartiQLParser.TableReferenceContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_tableReference) - self.state = 1062 + self.state = 1087 if not self.precpred(self._ctx, 4): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") - self.state = 1063 + self.state = 1088 self.match(PartiQLParser.COMMA) - self.state = 1064 + self.state = 1089 localctx.rhs = self.joinRhs() pass @@ -9491,30 +9627,30 @@ def tableReference(self, _p:int=0): localctx = PartiQLParser.TableQualifiedJoinContext(self, PartiQLParser.TableReferenceContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_tableReference) - self.state = 1065 + self.state = 1090 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 1067 + self.state = 1092 self._errHandler.sync(self) _la = self._input.LA(1) if ((((_la - 96)) & ~0x3f) == 0 and ((1 << (_la - 96)) & 144115188612734977) != 0) or _la==176: - self.state = 1066 + self.state = 1091 self.joinType() - self.state = 1069 + self.state = 1094 self.match(PartiQLParser.JOIN) - self.state = 1070 + self.state = 1095 localctx.rhs = self.joinRhs() - self.state = 1071 + self.state = 1096 self.joinSpec() pass - self.state = 1077 + self.state = 1102 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,120,self._ctx) + _alt = self._interp.adaptivePredict(self._input,124,self._ctx) except RecognitionException as re: localctx.exception = re @@ -9563,19 +9699,19 @@ def accept(self, visitor:ParseTreeVisitor): def tableNonJoin(self): localctx = PartiQLParser.TableNonJoinContext(self, self._ctx, self.state) - self.enterRule(localctx, 174, self.RULE_tableNonJoin) + self.enterRule(localctx, 176, self.RULE_tableNonJoin) try: - self.state = 1080 + self.state = 1105 self._errHandler.sync(self) token = self._input.LA(1) if token in [8, 15, 19, 23, 24, 28, 29, 32, 44, 48, 51, 53, 75, 79, 82, 85, 86, 87, 88, 129, 131, 132, 140, 141, 143, 145, 156, 160, 182, 187, 189, 195, 196, 201, 202, 207, 208, 213, 219, 230, 231, 234, 235, 236, 237, 266, 267, 271, 272, 275, 288, 290, 292, 294, 298, 300, 301, 302, 303, 304, 309]: self.enterOuterAlt(localctx, 1) - self.state = 1078 + self.state = 1103 self.tableBaseReference() pass elif token in [238]: self.enterOuterAlt(localctx, 2) - self.state = 1079 + self.state = 1104 self.tableUnpivot() pass else: @@ -9710,46 +9846,46 @@ def accept(self, visitor:ParseTreeVisitor): def tableBaseReference(self): localctx = PartiQLParser.TableBaseReferenceContext(self, self._ctx, self.state) - self.enterRule(localctx, 176, self.RULE_tableBaseReference) + self.enterRule(localctx, 178, self.RULE_tableBaseReference) try: - self.state = 1105 + self.state = 1130 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,128,self._ctx) + la_ = self._interp.adaptivePredict(self._input,132,self._ctx) if la_ == 1: localctx = PartiQLParser.TableBaseRefSymbolContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1082 + self.state = 1107 localctx.source = self.exprSelect() - self.state = 1083 + self.state = 1108 self.symbolPrimitive() pass elif la_ == 2: localctx = PartiQLParser.TableBaseRefClausesContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1085 + self.state = 1110 localctx.source = self.exprSelect() - self.state = 1087 + self.state = 1112 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,122,self._ctx) + la_ = self._interp.adaptivePredict(self._input,126,self._ctx) if la_ == 1: - self.state = 1086 + self.state = 1111 self.asIdent() - self.state = 1090 + self.state = 1115 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,123,self._ctx) + la_ = self._interp.adaptivePredict(self._input,127,self._ctx) if la_ == 1: - self.state = 1089 + self.state = 1114 self.atIdent() - self.state = 1093 + self.state = 1118 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,124,self._ctx) + la_ = self._interp.adaptivePredict(self._input,128,self._ctx) if la_ == 1: - self.state = 1092 + self.state = 1117 self.byIdent() @@ -9758,29 +9894,29 @@ def tableBaseReference(self): elif la_ == 3: localctx = PartiQLParser.TableBaseRefMatchContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1095 + self.state = 1120 localctx.source = self.exprGraphMatchOne() - self.state = 1097 + self.state = 1122 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,125,self._ctx) + la_ = self._interp.adaptivePredict(self._input,129,self._ctx) if la_ == 1: - self.state = 1096 + self.state = 1121 self.asIdent() - self.state = 1100 + self.state = 1125 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,126,self._ctx) + la_ = self._interp.adaptivePredict(self._input,130,self._ctx) if la_ == 1: - self.state = 1099 + self.state = 1124 self.atIdent() - self.state = 1103 + self.state = 1128 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,127,self._ctx) + la_ = self._interp.adaptivePredict(self._input,131,self._ctx) if la_ == 1: - self.state = 1102 + self.state = 1127 self.byIdent() @@ -9845,34 +9981,34 @@ def accept(self, visitor:ParseTreeVisitor): def tableUnpivot(self): localctx = PartiQLParser.TableUnpivotContext(self, self._ctx, self.state) - self.enterRule(localctx, 178, self.RULE_tableUnpivot) + self.enterRule(localctx, 180, self.RULE_tableUnpivot) try: self.enterOuterAlt(localctx, 1) - self.state = 1107 + self.state = 1132 self.match(PartiQLParser.UNPIVOT) - self.state = 1108 + self.state = 1133 self.expr() - self.state = 1110 + self.state = 1135 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,129,self._ctx) + la_ = self._interp.adaptivePredict(self._input,133,self._ctx) if la_ == 1: - self.state = 1109 + self.state = 1134 self.asIdent() - self.state = 1113 + self.state = 1138 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,130,self._ctx) + la_ = self._interp.adaptivePredict(self._input,134,self._ctx) if la_ == 1: - self.state = 1112 + self.state = 1137 self.atIdent() - self.state = 1116 + self.state = 1141 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,131,self._ctx) + la_ = self._interp.adaptivePredict(self._input,135,self._ctx) if la_ == 1: - self.state = 1115 + self.state = 1140 self.byIdent() @@ -9960,26 +10096,26 @@ def accept(self, visitor:ParseTreeVisitor): def joinRhs(self): localctx = PartiQLParser.JoinRhsContext(self, self._ctx, self.state) - self.enterRule(localctx, 180, self.RULE_joinRhs) + self.enterRule(localctx, 182, self.RULE_joinRhs) try: - self.state = 1123 + self.state = 1148 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,132,self._ctx) + la_ = self._interp.adaptivePredict(self._input,136,self._ctx) if la_ == 1: localctx = PartiQLParser.JoinRhsBaseContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1118 + self.state = 1143 self.tableNonJoin() pass elif la_ == 2: localctx = PartiQLParser.JoinRhsTableJoinedContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1119 + self.state = 1144 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1120 + self.state = 1145 self.tableReference(0) - self.state = 1121 + self.state = 1146 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -10030,12 +10166,12 @@ def accept(self, visitor:ParseTreeVisitor): def joinSpec(self): localctx = PartiQLParser.JoinSpecContext(self, self._ctx, self.state) - self.enterRule(localctx, 182, self.RULE_joinSpec) + self.enterRule(localctx, 184, self.RULE_joinSpec) try: self.enterOuterAlt(localctx, 1) - self.state = 1125 + self.state = 1150 self.match(PartiQLParser.ON) - self.state = 1126 + self.state = 1151 self.expr() except RecognitionException as re: localctx.exception = re @@ -10092,59 +10228,59 @@ def accept(self, visitor:ParseTreeVisitor): def joinType(self): localctx = PartiQLParser.JoinTypeContext(self, self._ctx, self.state) - self.enterRule(localctx, 184, self.RULE_joinType) + self.enterRule(localctx, 186, self.RULE_joinType) self._la = 0 # Token type try: - self.state = 1142 + self.state = 1167 self._errHandler.sync(self) token = self._input.LA(1) if token in [109]: self.enterOuterAlt(localctx, 1) - self.state = 1128 + self.state = 1153 localctx.mod = self.match(PartiQLParser.INNER) pass elif token in [125]: self.enterOuterAlt(localctx, 2) - self.state = 1129 + self.state = 1154 localctx.mod = self.match(PartiQLParser.LEFT) - self.state = 1131 + self.state = 1156 self._errHandler.sync(self) _la = self._input.LA(1) if _la==153: - self.state = 1130 + self.state = 1155 self.match(PartiQLParser.OUTER) pass elif token in [176]: self.enterOuterAlt(localctx, 3) - self.state = 1133 + self.state = 1158 localctx.mod = self.match(PartiQLParser.RIGHT) - self.state = 1135 + self.state = 1160 self._errHandler.sync(self) _la = self._input.LA(1) if _la==153: - self.state = 1134 + self.state = 1159 self.match(PartiQLParser.OUTER) pass elif token in [96]: self.enterOuterAlt(localctx, 4) - self.state = 1137 + self.state = 1162 localctx.mod = self.match(PartiQLParser.FULL) - self.state = 1139 + self.state = 1164 self._errHandler.sync(self) _la = self._input.LA(1) if _la==153: - self.state = 1138 + self.state = 1163 self.match(PartiQLParser.OUTER) pass elif token in [153]: self.enterOuterAlt(localctx, 5) - self.state = 1141 + self.state = 1166 localctx.mod = self.match(PartiQLParser.OUTER) pass else: @@ -10193,10 +10329,10 @@ def accept(self, visitor:ParseTreeVisitor): def expr(self): localctx = PartiQLParser.ExprContext(self, self._ctx, self.state) - self.enterRule(localctx, 186, self.RULE_expr) + self.enterRule(localctx, 188, self.RULE_expr) try: self.enterOuterAlt(localctx, 1) - self.state = 1144 + self.state = 1169 self.exprBagOp(0) except RecognitionException as re: localctx.exception = re @@ -10368,8 +10504,8 @@ def exprBagOp(self, _p:int=0): _parentState = self.state localctx = PartiQLParser.ExprBagOpContext(self, self._ctx, _parentState) _prevctx = localctx - _startState = 188 - self.enterRecursionRule(localctx, 188, self.RULE_exprBagOp, _p) + _startState = 190 + self.enterRecursionRule(localctx, 190, self.RULE_exprBagOp, _p) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) @@ -10377,43 +10513,43 @@ def exprBagOp(self, _p:int=0): self._ctx = localctx _prevctx = localctx - self.state = 1147 + self.state = 1172 self.exprSelect() self._ctx.stop = self._input.LT(-1) - self.state = 1178 + self.state = 1203 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,144,self._ctx) + _alt = self._interp.adaptivePredict(self._input,148,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 1176 + self.state = 1201 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,143,self._ctx) + la_ = self._interp.adaptivePredict(self._input,147,self._ctx) if la_ == 1: localctx = PartiQLParser.ExceptContext(self, PartiQLParser.ExprBagOpContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_exprBagOp) - self.state = 1149 + self.state = 1174 if not self.precpred(self._ctx, 4): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") - self.state = 1151 + self.state = 1176 self._errHandler.sync(self) _la = self._input.LA(1) if _la==153: - self.state = 1150 + self.state = 1175 self.match(PartiQLParser.OUTER) - self.state = 1153 + self.state = 1178 self.match(PartiQLParser.EXCEPT) - self.state = 1155 + self.state = 1180 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==67: - self.state = 1154 + self.state = 1179 _la = self._input.LA(1) if not(_la==4 or _la==67): self._errHandler.recoverInline(self) @@ -10422,7 +10558,7 @@ def exprBagOp(self, _p:int=0): self.consume() - self.state = 1157 + self.state = 1182 localctx.rhs = self.exprSelect() pass @@ -10430,25 +10566,25 @@ def exprBagOp(self, _p:int=0): localctx = PartiQLParser.UnionContext(self, PartiQLParser.ExprBagOpContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_exprBagOp) - self.state = 1158 + self.state = 1183 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 1160 + self.state = 1185 self._errHandler.sync(self) _la = self._input.LA(1) if _la==153: - self.state = 1159 + self.state = 1184 self.match(PartiQLParser.OUTER) - self.state = 1162 + self.state = 1187 self.match(PartiQLParser.UNION) - self.state = 1164 + self.state = 1189 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==67: - self.state = 1163 + self.state = 1188 _la = self._input.LA(1) if not(_la==4 or _la==67): self._errHandler.recoverInline(self) @@ -10457,7 +10593,7 @@ def exprBagOp(self, _p:int=0): self.consume() - self.state = 1166 + self.state = 1191 localctx.rhs = self.exprSelect() pass @@ -10465,25 +10601,25 @@ def exprBagOp(self, _p:int=0): localctx = PartiQLParser.IntersectContext(self, PartiQLParser.ExprBagOpContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_exprBagOp) - self.state = 1167 + self.state = 1192 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1169 + self.state = 1194 self._errHandler.sync(self) _la = self._input.LA(1) if _la==153: - self.state = 1168 + self.state = 1193 self.match(PartiQLParser.OUTER) - self.state = 1171 + self.state = 1196 self.match(PartiQLParser.INTERSECT) - self.state = 1173 + self.state = 1198 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==67: - self.state = 1172 + self.state = 1197 _la = self._input.LA(1) if not(_la==4 or _la==67): self._errHandler.recoverInline(self) @@ -10492,14 +10628,14 @@ def exprBagOp(self, _p:int=0): self.consume() - self.state = 1175 + self.state = 1200 localctx.rhs = self.exprSelect() pass - self.state = 1180 + self.state = 1205 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,144,self._ctx) + _alt = self._interp.adaptivePredict(self._input,148,self._ctx) except RecognitionException as re: localctx.exception = re @@ -10618,80 +10754,80 @@ def accept(self, visitor:ParseTreeVisitor): def exprSelect(self): localctx = PartiQLParser.ExprSelectContext(self, self._ctx, self.state) - self.enterRule(localctx, 190, self.RULE_exprSelect) + self.enterRule(localctx, 192, self.RULE_exprSelect) self._la = 0 # Token type try: - self.state = 1208 + self.state = 1233 self._errHandler.sync(self) token = self._input.LA(1) if token in [182, 237]: localctx = PartiQLParser.SfwQueryContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1181 + self.state = 1206 localctx.select = self.selectClause() - self.state = 1183 + self.state = 1208 self._errHandler.sync(self) _la = self._input.LA(1) if _la==78: - self.state = 1182 + self.state = 1207 localctx.exclude = self.excludeClause() - self.state = 1185 + self.state = 1210 localctx.from_ = self.fromClause() - self.state = 1187 + self.state = 1212 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,146,self._ctx) + la_ = self._interp.adaptivePredict(self._input,150,self._ctx) if la_ == 1: - self.state = 1186 + self.state = 1211 localctx.let = self.letClause() - self.state = 1190 + self.state = 1215 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,147,self._ctx) + la_ = self._interp.adaptivePredict(self._input,151,self._ctx) if la_ == 1: - self.state = 1189 + self.state = 1214 localctx.where = self.whereClauseSelect() - self.state = 1193 + self.state = 1218 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,148,self._ctx) + la_ = self._interp.adaptivePredict(self._input,152,self._ctx) if la_ == 1: - self.state = 1192 + self.state = 1217 localctx.group = self.groupClause() - self.state = 1196 + self.state = 1221 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,149,self._ctx) + la_ = self._interp.adaptivePredict(self._input,153,self._ctx) if la_ == 1: - self.state = 1195 + self.state = 1220 localctx.having = self.havingClause() - self.state = 1199 + self.state = 1224 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,150,self._ctx) + la_ = self._interp.adaptivePredict(self._input,154,self._ctx) if la_ == 1: - self.state = 1198 + self.state = 1223 localctx.order = self.orderByClause() - self.state = 1202 + self.state = 1227 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,151,self._ctx) + la_ = self._interp.adaptivePredict(self._input,155,self._ctx) if la_ == 1: - self.state = 1201 + self.state = 1226 localctx.limit = self.limitClause() - self.state = 1205 + self.state = 1230 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,152,self._ctx) + la_ = self._interp.adaptivePredict(self._input,156,self._ctx) if la_ == 1: - self.state = 1204 + self.state = 1229 localctx.offset = self.offsetByClause() @@ -10699,7 +10835,7 @@ def exprSelect(self): elif token in [8, 15, 19, 23, 24, 28, 29, 32, 44, 48, 51, 53, 75, 79, 82, 85, 86, 87, 88, 129, 131, 132, 140, 141, 143, 145, 156, 160, 187, 189, 195, 196, 201, 202, 207, 208, 213, 219, 230, 231, 234, 235, 236, 266, 267, 271, 272, 275, 288, 290, 292, 294, 298, 300, 301, 302, 303, 304, 309]: localctx = PartiQLParser.SfwBaseContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1207 + self.state = 1232 self.exprOr(0) pass else: @@ -10794,20 +10930,20 @@ def exprOr(self, _p:int=0): _parentState = self.state localctx = PartiQLParser.ExprOrContext(self, self._ctx, _parentState) _prevctx = localctx - _startState = 192 - self.enterRecursionRule(localctx, 192, self.RULE_exprOr, _p) + _startState = 194 + self.enterRecursionRule(localctx, 194, self.RULE_exprOr, _p) try: self.enterOuterAlt(localctx, 1) localctx = PartiQLParser.ExprOrBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1211 + self.state = 1236 localctx.parent_ = self.exprAnd(0) self._ctx.stop = self._input.LT(-1) - self.state = 1218 + self.state = 1243 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,154,self._ctx) + _alt = self._interp.adaptivePredict(self._input,158,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: @@ -10816,17 +10952,17 @@ def exprOr(self, _p:int=0): localctx = PartiQLParser.OrContext(self, PartiQLParser.ExprOrContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_exprOr) - self.state = 1213 + self.state = 1238 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1214 + self.state = 1239 self.match(PartiQLParser.OR) - self.state = 1215 + self.state = 1240 localctx.rhs = self.exprAnd(0) - self.state = 1220 + self.state = 1245 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,154,self._ctx) + _alt = self._interp.adaptivePredict(self._input,158,self._ctx) except RecognitionException as re: localctx.exception = re @@ -10918,20 +11054,20 @@ def exprAnd(self, _p:int=0): _parentState = self.state localctx = PartiQLParser.ExprAndContext(self, self._ctx, _parentState) _prevctx = localctx - _startState = 194 - self.enterRecursionRule(localctx, 194, self.RULE_exprAnd, _p) + _startState = 196 + self.enterRecursionRule(localctx, 196, self.RULE_exprAnd, _p) try: self.enterOuterAlt(localctx, 1) localctx = PartiQLParser.ExprAndBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1222 + self.state = 1247 localctx.parent_ = self.exprNot() self._ctx.stop = self._input.LT(-1) - self.state = 1229 + self.state = 1254 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,155,self._ctx) + _alt = self._interp.adaptivePredict(self._input,159,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: @@ -10940,17 +11076,17 @@ def exprAnd(self, _p:int=0): localctx = PartiQLParser.AndContext(self, PartiQLParser.ExprAndContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_exprAnd) - self.state = 1224 + self.state = 1249 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1225 + self.state = 1250 localctx.op = self.match(PartiQLParser.AND) - self.state = 1226 + self.state = 1251 localctx.rhs = self.exprNot() - self.state = 1231 + self.state = 1256 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,155,self._ctx) + _alt = self._interp.adaptivePredict(self._input,159,self._ctx) except RecognitionException as re: localctx.exception = re @@ -11037,23 +11173,23 @@ def accept(self, visitor:ParseTreeVisitor): def exprNot(self): localctx = PartiQLParser.ExprNotContext(self, self._ctx, self.state) - self.enterRule(localctx, 196, self.RULE_exprNot) + self.enterRule(localctx, 198, self.RULE_exprNot) try: - self.state = 1235 + self.state = 1260 self._errHandler.sync(self) token = self._input.LA(1) if token in [140]: localctx = PartiQLParser.NotContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1232 + self.state = 1257 localctx.op = self.match(PartiQLParser.NOT) - self.state = 1233 + self.state = 1258 localctx.rhs = self.exprNot() pass elif token in [8, 15, 19, 23, 24, 28, 29, 32, 44, 48, 51, 53, 75, 79, 82, 85, 86, 87, 88, 129, 131, 132, 141, 143, 145, 156, 160, 187, 189, 195, 196, 201, 202, 207, 208, 213, 219, 230, 231, 234, 235, 236, 266, 267, 271, 272, 275, 288, 290, 292, 294, 298, 300, 301, 302, 303, 304, 309]: localctx = PartiQLParser.ExprNotBaseContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1234 + self.state = 1259 localctx.parent_ = self.exprPredicate(0) pass else: @@ -11313,8 +11449,8 @@ def exprPredicate(self, _p:int=0): _parentState = self.state localctx = PartiQLParser.ExprPredicateContext(self, self._ctx, _parentState) _prevctx = localctx - _startState = 198 - self.enterRecursionRule(localctx, 198, self.RULE_exprPredicate, _p) + _startState = 200 + self.enterRecursionRule(localctx, 200, self.RULE_exprPredicate, _p) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) @@ -11322,29 +11458,29 @@ def exprPredicate(self, _p:int=0): self._ctx = localctx _prevctx = localctx - self.state = 1238 + self.state = 1263 localctx.parent_ = self.mathOp00(0) self._ctx.stop = self._input.LT(-1) - self.state = 1285 + self.state = 1310 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,164,self._ctx) + _alt = self._interp.adaptivePredict(self._input,168,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 1283 + self.state = 1308 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,163,self._ctx) + la_ = self._interp.adaptivePredict(self._input,167,self._ctx) if la_ == 1: localctx = PartiQLParser.PredicateComparisonContext(self, PartiQLParser.ExprPredicateContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_exprPredicate) - self.state = 1240 + self.state = 1265 if not self.precpred(self._ctx, 7): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 7)") - self.state = 1241 + self.state = 1266 localctx.op = self._input.LT(1) _la = self._input.LA(1) if not(((((_la - 281)) & ~0x3f) == 0 and ((1 << (_la - 281)) & 111) != 0)): @@ -11352,7 +11488,7 @@ def exprPredicate(self, _p:int=0): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1242 + self.state = 1267 localctx.rhs = self.mathOp00(0) pass @@ -11360,21 +11496,21 @@ def exprPredicate(self, _p:int=0): localctx = PartiQLParser.PredicateIsContext(self, PartiQLParser.ExprPredicateContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_exprPredicate) - self.state = 1243 + self.state = 1268 if not self.precpred(self._ctx, 6): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 6)") - self.state = 1244 + self.state = 1269 self.match(PartiQLParser.IS) - self.state = 1246 + self.state = 1271 self._errHandler.sync(self) _la = self._input.LA(1) if _la==140: - self.state = 1245 + self.state = 1270 self.match(PartiQLParser.NOT) - self.state = 1248 + self.state = 1273 self.type_() pass @@ -11382,25 +11518,25 @@ def exprPredicate(self, _p:int=0): localctx = PartiQLParser.PredicateInContext(self, PartiQLParser.ExprPredicateContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_exprPredicate) - self.state = 1249 + self.state = 1274 if not self.precpred(self._ctx, 5): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") - self.state = 1251 + self.state = 1276 self._errHandler.sync(self) _la = self._input.LA(1) if _la==140: - self.state = 1250 + self.state = 1275 self.match(PartiQLParser.NOT) - self.state = 1253 + self.state = 1278 self.match(PartiQLParser.IN) - self.state = 1254 + self.state = 1279 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1255 + self.state = 1280 self.expr() - self.state = 1256 + self.state = 1281 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -11408,21 +11544,21 @@ def exprPredicate(self, _p:int=0): localctx = PartiQLParser.PredicateInContext(self, PartiQLParser.ExprPredicateContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_exprPredicate) - self.state = 1258 + self.state = 1283 if not self.precpred(self._ctx, 4): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") - self.state = 1260 + self.state = 1285 self._errHandler.sync(self) _la = self._input.LA(1) if _la==140: - self.state = 1259 + self.state = 1284 self.match(PartiQLParser.NOT) - self.state = 1262 + self.state = 1287 self.match(PartiQLParser.IN) - self.state = 1263 + self.state = 1288 localctx.rhs = self.mathOp00(0) pass @@ -11430,29 +11566,29 @@ def exprPredicate(self, _p:int=0): localctx = PartiQLParser.PredicateLikeContext(self, PartiQLParser.ExprPredicateContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_exprPredicate) - self.state = 1264 + self.state = 1289 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 1266 + self.state = 1291 self._errHandler.sync(self) _la = self._input.LA(1) if _la==140: - self.state = 1265 + self.state = 1290 self.match(PartiQLParser.NOT) - self.state = 1268 + self.state = 1293 self.match(PartiQLParser.LIKE) - self.state = 1269 + self.state = 1294 localctx.rhs = self.mathOp00(0) - self.state = 1272 + self.state = 1297 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,161,self._ctx) + la_ = self._interp.adaptivePredict(self._input,165,self._ctx) if la_ == 1: - self.state = 1270 + self.state = 1295 self.match(PartiQLParser.ESCAPE) - self.state = 1271 + self.state = 1296 localctx.escape = self.expr() @@ -11462,32 +11598,32 @@ def exprPredicate(self, _p:int=0): localctx = PartiQLParser.PredicateBetweenContext(self, PartiQLParser.ExprPredicateContext(self, _parentctx, _parentState)) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_exprPredicate) - self.state = 1274 + self.state = 1299 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1276 + self.state = 1301 self._errHandler.sync(self) _la = self._input.LA(1) if _la==140: - self.state = 1275 + self.state = 1300 self.match(PartiQLParser.NOT) - self.state = 1278 + self.state = 1303 self.match(PartiQLParser.BETWEEN) - self.state = 1279 + self.state = 1304 localctx.lower = self.mathOp00(0) - self.state = 1280 + self.state = 1305 self.match(PartiQLParser.AND) - self.state = 1281 + self.state = 1306 localctx.upper = self.mathOp00(0) pass - self.state = 1287 + self.state = 1312 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,164,self._ctx) + _alt = self._interp.adaptivePredict(self._input,168,self._ctx) except RecognitionException as re: localctx.exception = re @@ -11547,17 +11683,17 @@ def mathOp00(self, _p:int=0): _parentState = self.state localctx = PartiQLParser.MathOp00Context(self, self._ctx, _parentState) _prevctx = localctx - _startState = 200 - self.enterRecursionRule(localctx, 200, self.RULE_mathOp00, _p) + _startState = 202 + self.enterRecursionRule(localctx, 202, self.RULE_mathOp00, _p) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1289 + self.state = 1314 localctx.parent_ = self.mathOp01(0) self._ctx.stop = self._input.LT(-1) - self.state = 1296 + self.state = 1321 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,165,self._ctx) + _alt = self._interp.adaptivePredict(self._input,169,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: @@ -11566,11 +11702,11 @@ def mathOp00(self, _p:int=0): localctx = PartiQLParser.MathOp00Context(self, _parentctx, _parentState) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_mathOp00) - self.state = 1291 + self.state = 1316 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1292 + self.state = 1317 localctx.op = self._input.LT(1) _la = self._input.LA(1) if not(_la==279 or _la==285): @@ -11578,11 +11714,11 @@ def mathOp00(self, _p:int=0): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1293 + self.state = 1318 localctx.rhs = self.mathOp01(0) - self.state = 1298 + self.state = 1323 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,165,self._ctx) + _alt = self._interp.adaptivePredict(self._input,169,self._ctx) except RecognitionException as re: localctx.exception = re @@ -11642,17 +11778,17 @@ def mathOp01(self, _p:int=0): _parentState = self.state localctx = PartiQLParser.MathOp01Context(self, self._ctx, _parentState) _prevctx = localctx - _startState = 202 - self.enterRecursionRule(localctx, 202, self.RULE_mathOp01, _p) + _startState = 204 + self.enterRecursionRule(localctx, 204, self.RULE_mathOp01, _p) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1300 + self.state = 1325 localctx.parent_ = self.mathOp02(0) self._ctx.stop = self._input.LT(-1) - self.state = 1307 + self.state = 1332 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,166,self._ctx) + _alt = self._interp.adaptivePredict(self._input,170,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: @@ -11661,11 +11797,11 @@ def mathOp01(self, _p:int=0): localctx = PartiQLParser.MathOp01Context(self, _parentctx, _parentState) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_mathOp01) - self.state = 1302 + self.state = 1327 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1303 + self.state = 1328 localctx.op = self._input.LT(1) _la = self._input.LA(1) if not(_la==271 or _la==272): @@ -11673,11 +11809,11 @@ def mathOp01(self, _p:int=0): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1304 + self.state = 1329 localctx.rhs = self.mathOp02(0) - self.state = 1309 + self.state = 1334 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,166,self._ctx) + _alt = self._interp.adaptivePredict(self._input,170,self._ctx) except RecognitionException as re: localctx.exception = re @@ -11740,17 +11876,17 @@ def mathOp02(self, _p:int=0): _parentState = self.state localctx = PartiQLParser.MathOp02Context(self, self._ctx, _parentState) _prevctx = localctx - _startState = 204 - self.enterRecursionRule(localctx, 204, self.RULE_mathOp02, _p) + _startState = 206 + self.enterRecursionRule(localctx, 206, self.RULE_mathOp02, _p) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1311 + self.state = 1336 localctx.parent_ = self.valueExpr() self._ctx.stop = self._input.LT(-1) - self.state = 1318 + self.state = 1343 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,167,self._ctx) + _alt = self._interp.adaptivePredict(self._input,171,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: @@ -11759,11 +11895,11 @@ def mathOp02(self, _p:int=0): localctx = PartiQLParser.MathOp02Context(self, _parentctx, _parentState) localctx.lhs = _prevctx self.pushNewRecursionContext(localctx, _startState, self.RULE_mathOp02) - self.state = 1313 + self.state = 1338 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1314 + self.state = 1339 localctx.op = self._input.LT(1) _la = self._input.LA(1) if not(((((_la - 273)) & ~0x3f) == 0 and ((1 << (_la - 273)) & 19) != 0)): @@ -11771,11 +11907,11 @@ def mathOp02(self, _p:int=0): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1315 + self.state = 1340 localctx.rhs = self.valueExpr() - self.state = 1320 + self.state = 1345 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,167,self._ctx) + _alt = self._interp.adaptivePredict(self._input,171,self._ctx) except RecognitionException as re: localctx.exception = re @@ -11833,15 +11969,15 @@ def accept(self, visitor:ParseTreeVisitor): def valueExpr(self): localctx = PartiQLParser.ValueExprContext(self, self._ctx, self.state) - self.enterRule(localctx, 206, self.RULE_valueExpr) + self.enterRule(localctx, 208, self.RULE_valueExpr) self._la = 0 # Token type try: - self.state = 1324 + self.state = 1349 self._errHandler.sync(self) token = self._input.LA(1) if token in [271, 272]: self.enterOuterAlt(localctx, 1) - self.state = 1321 + self.state = 1346 localctx.sign = self._input.LT(1) _la = self._input.LA(1) if not(_la==271 or _la==272): @@ -11849,12 +11985,12 @@ def valueExpr(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1322 + self.state = 1347 localctx.rhs = self.valueExpr() pass elif token in [8, 15, 19, 23, 24, 28, 29, 32, 44, 48, 51, 53, 75, 79, 82, 85, 86, 87, 88, 129, 131, 132, 141, 143, 145, 156, 160, 187, 189, 195, 196, 201, 202, 207, 208, 213, 219, 230, 231, 234, 235, 236, 266, 267, 275, 288, 290, 292, 294, 298, 300, 301, 302, 303, 304, 309]: self.enterOuterAlt(localctx, 2) - self.state = 1323 + self.state = 1348 localctx.parent_ = self.exprPrimary(0) pass else: @@ -12004,19 +12140,19 @@ def exprPrimary(self, _p:int=0): _parentState = self.state localctx = PartiQLParser.ExprPrimaryContext(self, self._ctx, _parentState) _prevctx = localctx - _startState = 208 - self.enterRecursionRule(localctx, 208, self.RULE_exprPrimary, _p) + _startState = 210 + self.enterRecursionRule(localctx, 210, self.RULE_exprPrimary, _p) try: self.enterOuterAlt(localctx, 1) - self.state = 1347 + self.state = 1372 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,169,self._ctx) + la_ = self._interp.adaptivePredict(self._input,173,self._ctx) if la_ == 1: localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1327 + self.state = 1352 self.exprTerm() pass @@ -12024,7 +12160,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1328 + self.state = 1353 self.cast() pass @@ -12032,7 +12168,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1329 + self.state = 1354 self.sequenceConstructor() pass @@ -12040,7 +12176,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1330 + self.state = 1355 self.substring() pass @@ -12048,7 +12184,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1331 + self.state = 1356 self.position() pass @@ -12056,7 +12192,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1332 + self.state = 1357 self.overlay() pass @@ -12064,7 +12200,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1333 + self.state = 1358 self.canCast() pass @@ -12072,7 +12208,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1334 + self.state = 1359 self.canLosslessCast() pass @@ -12080,7 +12216,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1335 + self.state = 1360 self.extract() pass @@ -12088,7 +12224,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1336 + self.state = 1361 self.coalesce() pass @@ -12096,7 +12232,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1337 + self.state = 1362 self.dateFunction() pass @@ -12104,7 +12240,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1338 + self.state = 1363 self.aggregate() pass @@ -12112,7 +12248,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1339 + self.state = 1364 self.trimFunction() pass @@ -12120,7 +12256,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1340 + self.state = 1365 self.functionCall() pass @@ -12128,7 +12264,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1341 + self.state = 1366 self.nullIf() pass @@ -12136,7 +12272,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1342 + self.state = 1367 self.exprGraphMatchMany() pass @@ -12144,7 +12280,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1343 + self.state = 1368 self.caseExpr() pass @@ -12152,7 +12288,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1344 + self.state = 1369 self.valueList() pass @@ -12160,7 +12296,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1345 + self.state = 1370 self.values() pass @@ -12168,15 +12304,15 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1346 + self.state = 1371 self.windowFunction() pass self._ctx.stop = self._input.LT(-1) - self.state = 1357 + self.state = 1382 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,171,self._ctx) + _alt = self._interp.adaptivePredict(self._input,175,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: if self._parseListeners is not None: @@ -12184,27 +12320,27 @@ def exprPrimary(self, _p:int=0): _prevctx = localctx localctx = PartiQLParser.ExprPrimaryPathContext(self, PartiQLParser.ExprPrimaryContext(self, _parentctx, _parentState)) self.pushNewRecursionContext(localctx, _startState, self.RULE_exprPrimary) - self.state = 1349 + self.state = 1374 if not self.precpred(self._ctx, 6): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 6)") - self.state = 1351 + self.state = 1376 self._errHandler.sync(self) _alt = 1 while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt == 1: - self.state = 1350 + self.state = 1375 self.pathStep() else: raise NoViableAltException(self) - self.state = 1353 + self.state = 1378 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,170,self._ctx) + _alt = self._interp.adaptivePredict(self._input,174,self._ctx) - self.state = 1359 + self.state = 1384 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,171,self._ctx) + _alt = self._interp.adaptivePredict(self._input,175,self._ctx) except RecognitionException as re: localctx.exception = re @@ -12350,61 +12486,61 @@ def accept(self, visitor:ParseTreeVisitor): def exprTerm(self): localctx = PartiQLParser.ExprTermContext(self, self._ctx, self.state) - self.enterRule(localctx, 210, self.RULE_exprTerm) + self.enterRule(localctx, 212, self.RULE_exprTerm) try: - self.state = 1371 + self.state = 1396 self._errHandler.sync(self) token = self._input.LA(1) if token in [294]: localctx = PartiQLParser.ExprTermWrappedQueryContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1360 + self.state = 1385 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1361 + self.state = 1386 self.expr() - self.state = 1362 + self.state = 1387 self.match(PartiQLParser.PAREN_RIGHT) pass elif token in [51]: localctx = PartiQLParser.ExprTermCurrentUserContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1364 + self.state = 1389 self.match(PartiQLParser.CURRENT_USER) pass elif token in [48]: localctx = PartiQLParser.ExprTermCurrentDateContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1365 + self.state = 1390 self.match(PartiQLParser.CURRENT_DATE) pass elif token in [298]: localctx = PartiQLParser.ExprTermBaseContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 1366 + self.state = 1391 self.parameter() pass elif token in [79, 275, 303, 304]: localctx = PartiQLParser.ExprTermBaseContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 1367 + self.state = 1392 self.varRefExpr() pass elif token in [53, 88, 141, 201, 202, 208, 236, 300, 301, 302, 309]: localctx = PartiQLParser.ExprTermBaseContext(self, localctx) self.enterOuterAlt(localctx, 6) - self.state = 1368 + self.state = 1393 self.literal() pass elif token in [288, 290]: localctx = PartiQLParser.ExprTermBaseContext(self, localctx) self.enterOuterAlt(localctx, 7) - self.state = 1369 + self.state = 1394 self.collection() pass elif token in [292]: localctx = PartiQLParser.ExprTermBaseContext(self, localctx) self.enterOuterAlt(localctx, 8) - self.state = 1370 + self.state = 1395 self.tuple_() pass else: @@ -12468,20 +12604,20 @@ def accept(self, visitor:ParseTreeVisitor): def nullIf(self): localctx = PartiQLParser.NullIfContext(self, self._ctx, self.state) - self.enterRule(localctx, 212, self.RULE_nullIf) + self.enterRule(localctx, 214, self.RULE_nullIf) try: self.enterOuterAlt(localctx, 1) - self.state = 1373 + self.state = 1398 self.match(PartiQLParser.NULLIF) - self.state = 1374 + self.state = 1399 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1375 + self.state = 1400 self.expr() - self.state = 1376 + self.state = 1401 self.match(PartiQLParser.COMMA) - self.state = 1377 + self.state = 1402 self.expr() - self.state = 1378 + self.state = 1403 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -12544,29 +12680,29 @@ def accept(self, visitor:ParseTreeVisitor): def coalesce(self): localctx = PartiQLParser.CoalesceContext(self, self._ctx, self.state) - self.enterRule(localctx, 214, self.RULE_coalesce) + self.enterRule(localctx, 216, self.RULE_coalesce) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1380 + self.state = 1405 self.match(PartiQLParser.COALESCE) - self.state = 1381 + self.state = 1406 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1382 + self.state = 1407 self.expr() - self.state = 1387 + self.state = 1412 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 1383 + self.state = 1408 self.match(PartiQLParser.COMMA) - self.state = 1384 + self.state = 1409 self.expr() - self.state = 1389 + self.state = 1414 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1390 + self.state = 1415 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -12640,51 +12776,51 @@ def accept(self, visitor:ParseTreeVisitor): def caseExpr(self): localctx = PartiQLParser.CaseExprContext(self, self._ctx, self.state) - self.enterRule(localctx, 216, self.RULE_caseExpr) + self.enterRule(localctx, 218, self.RULE_caseExpr) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1392 + self.state = 1417 self.match(PartiQLParser.CASE) - self.state = 1394 + self.state = 1419 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 11558071357178112) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 234187180623281297) != 0) or ((((_la - 140)) & ~0x3f) == 0 and ((1 << (_la - 140)) & 7026323504187375659) != 0) or ((((_la - 207)) & ~0x3f) == 0 and ((1 << (_la - 207)) & 1729382258948706371) != 0) or ((((_la - 271)) & ~0x3f) == 0 and ((1 << (_la - 271)) & 291666264083) != 0): - self.state = 1393 + self.state = 1418 localctx.case = self.expr() - self.state = 1401 + self.state = 1426 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 1396 + self.state = 1421 self.match(PartiQLParser.WHEN) - self.state = 1397 + self.state = 1422 localctx._expr = self.expr() localctx.whens.append(localctx._expr) - self.state = 1398 + self.state = 1423 self.match(PartiQLParser.THEN) - self.state = 1399 + self.state = 1424 localctx._expr = self.expr() localctx.thens.append(localctx._expr) - self.state = 1403 + self.state = 1428 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==223): break - self.state = 1407 + self.state = 1432 self._errHandler.sync(self) _la = self._input.LA(1) if _la==71: - self.state = 1405 + self.state = 1430 self.match(PartiQLParser.ELSE) - self.state = 1406 + self.state = 1431 localctx.else_ = self.expr() - self.state = 1409 + self.state = 1434 self.match(PartiQLParser.END) except RecognitionException as re: localctx.exception = re @@ -12741,25 +12877,25 @@ def accept(self, visitor:ParseTreeVisitor): def values(self): localctx = PartiQLParser.ValuesContext(self, self._ctx, self.state) - self.enterRule(localctx, 218, self.RULE_values) + self.enterRule(localctx, 220, self.RULE_values) try: self.enterOuterAlt(localctx, 1) - self.state = 1411 + self.state = 1436 self.match(PartiQLParser.VALUES) - self.state = 1412 + self.state = 1437 self.valueRow() - self.state = 1417 + self.state = 1442 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,177,self._ctx) + _alt = self._interp.adaptivePredict(self._input,181,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 1413 + self.state = 1438 self.match(PartiQLParser.COMMA) - self.state = 1414 + self.state = 1439 self.valueRow() - self.state = 1419 + self.state = 1444 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,177,self._ctx) + _alt = self._interp.adaptivePredict(self._input,181,self._ctx) except RecognitionException as re: localctx.exception = re @@ -12819,27 +12955,27 @@ def accept(self, visitor:ParseTreeVisitor): def valueRow(self): localctx = PartiQLParser.ValueRowContext(self, self._ctx, self.state) - self.enterRule(localctx, 220, self.RULE_valueRow) + self.enterRule(localctx, 222, self.RULE_valueRow) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1420 + self.state = 1445 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1421 + self.state = 1446 self.expr() - self.state = 1426 + self.state = 1451 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 1422 + self.state = 1447 self.match(PartiQLParser.COMMA) - self.state = 1423 + self.state = 1448 self.expr() - self.state = 1428 + self.state = 1453 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1429 + self.state = 1454 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -12899,29 +13035,29 @@ def accept(self, visitor:ParseTreeVisitor): def valueList(self): localctx = PartiQLParser.ValueListContext(self, self._ctx, self.state) - self.enterRule(localctx, 222, self.RULE_valueList) + self.enterRule(localctx, 224, self.RULE_valueList) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1431 + self.state = 1456 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1432 + self.state = 1457 self.expr() - self.state = 1435 + self.state = 1460 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 1433 + self.state = 1458 self.match(PartiQLParser.COMMA) - self.state = 1434 + self.state = 1459 self.expr() - self.state = 1437 + self.state = 1462 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==270): break - self.state = 1439 + self.state = 1464 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -12988,11 +13124,11 @@ def accept(self, visitor:ParseTreeVisitor): def sequenceConstructor(self): localctx = PartiQLParser.SequenceConstructorContext(self, self._ctx, self.state) - self.enterRule(localctx, 224, self.RULE_sequenceConstructor) + self.enterRule(localctx, 226, self.RULE_sequenceConstructor) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1441 + self.state = 1466 localctx.datatype = self._input.LT(1) _la = self._input.LA(1) if not(_la==266 or _la==267): @@ -13000,29 +13136,29 @@ def sequenceConstructor(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1442 + self.state = 1467 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1451 + self.state = 1476 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 11558071357178112) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 234187180623281297) != 0) or ((((_la - 140)) & ~0x3f) == 0 and ((1 << (_la - 140)) & 7026323504187375659) != 0) or ((((_la - 207)) & ~0x3f) == 0 and ((1 << (_la - 207)) & 1729382258948706371) != 0) or ((((_la - 271)) & ~0x3f) == 0 and ((1 << (_la - 271)) & 291666264083) != 0): - self.state = 1443 + self.state = 1468 self.expr() - self.state = 1448 + self.state = 1473 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 1444 + self.state = 1469 self.match(PartiQLParser.COMMA) - self.state = 1445 + self.state = 1470 self.expr() - self.state = 1450 + self.state = 1475 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1453 + self.state = 1478 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -13091,73 +13227,73 @@ def accept(self, visitor:ParseTreeVisitor): def substring(self): localctx = PartiQLParser.SubstringContext(self, self._ctx, self.state) - self.enterRule(localctx, 226, self.RULE_substring) + self.enterRule(localctx, 228, self.RULE_substring) self._la = 0 # Token type try: - self.state = 1481 + self.state = 1506 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,186,self._ctx) + la_ = self._interp.adaptivePredict(self._input,190,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 1455 + self.state = 1480 self.match(PartiQLParser.SUBSTRING) - self.state = 1456 + self.state = 1481 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1457 + self.state = 1482 self.expr() - self.state = 1464 + self.state = 1489 self._errHandler.sync(self) _la = self._input.LA(1) if _la==270: - self.state = 1458 + self.state = 1483 self.match(PartiQLParser.COMMA) - self.state = 1459 + self.state = 1484 self.expr() - self.state = 1462 + self.state = 1487 self._errHandler.sync(self) _la = self._input.LA(1) if _la==270: - self.state = 1460 + self.state = 1485 self.match(PartiQLParser.COMMA) - self.state = 1461 + self.state = 1486 self.expr() - self.state = 1466 + self.state = 1491 self.match(PartiQLParser.PAREN_RIGHT) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 1468 + self.state = 1493 self.match(PartiQLParser.SUBSTRING) - self.state = 1469 + self.state = 1494 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1470 + self.state = 1495 self.expr() - self.state = 1477 + self.state = 1502 self._errHandler.sync(self) _la = self._input.LA(1) if _la==95: - self.state = 1471 + self.state = 1496 self.match(PartiQLParser.FROM) - self.state = 1472 + self.state = 1497 self.expr() - self.state = 1475 + self.state = 1500 self._errHandler.sync(self) _la = self._input.LA(1) if _la==92: - self.state = 1473 + self.state = 1498 self.match(PartiQLParser.FOR) - self.state = 1474 + self.state = 1499 self.expr() - self.state = 1479 + self.state = 1504 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -13223,40 +13359,40 @@ def accept(self, visitor:ParseTreeVisitor): def position(self): localctx = PartiQLParser.PositionContext(self, self._ctx, self.state) - self.enterRule(localctx, 228, self.RULE_position) + self.enterRule(localctx, 230, self.RULE_position) try: - self.state = 1497 + self.state = 1522 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,187,self._ctx) + la_ = self._interp.adaptivePredict(self._input,191,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 1483 + self.state = 1508 self.match(PartiQLParser.POSITION) - self.state = 1484 + self.state = 1509 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1485 + self.state = 1510 self.expr() - self.state = 1486 + self.state = 1511 self.match(PartiQLParser.COMMA) - self.state = 1487 + self.state = 1512 self.expr() - self.state = 1488 + self.state = 1513 self.match(PartiQLParser.PAREN_RIGHT) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 1490 + self.state = 1515 self.match(PartiQLParser.POSITION) - self.state = 1491 + self.state = 1516 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1492 + self.state = 1517 self.expr() - self.state = 1493 + self.state = 1518 self.match(PartiQLParser.IN) - self.state = 1494 + self.state = 1519 self.expr() - self.state = 1495 + self.state = 1520 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -13331,69 +13467,69 @@ def accept(self, visitor:ParseTreeVisitor): def overlay(self): localctx = PartiQLParser.OverlayContext(self, self._ctx, self.state) - self.enterRule(localctx, 230, self.RULE_overlay) + self.enterRule(localctx, 232, self.RULE_overlay) self._la = 0 # Token type try: - self.state = 1525 + self.state = 1550 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,190,self._ctx) + la_ = self._interp.adaptivePredict(self._input,194,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 1499 + self.state = 1524 self.match(PartiQLParser.OVERLAY) - self.state = 1500 + self.state = 1525 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1501 + self.state = 1526 self.expr() - self.state = 1502 + self.state = 1527 self.match(PartiQLParser.COMMA) - self.state = 1503 + self.state = 1528 self.expr() - self.state = 1504 + self.state = 1529 self.match(PartiQLParser.COMMA) - self.state = 1505 + self.state = 1530 self.expr() - self.state = 1508 + self.state = 1533 self._errHandler.sync(self) _la = self._input.LA(1) if _la==270: - self.state = 1506 + self.state = 1531 self.match(PartiQLParser.COMMA) - self.state = 1507 + self.state = 1532 self.expr() - self.state = 1510 + self.state = 1535 self.match(PartiQLParser.PAREN_RIGHT) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 1512 + self.state = 1537 self.match(PartiQLParser.OVERLAY) - self.state = 1513 + self.state = 1538 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1514 + self.state = 1539 self.expr() - self.state = 1515 + self.state = 1540 self.match(PartiQLParser.PLACING) - self.state = 1516 + self.state = 1541 self.expr() - self.state = 1517 + self.state = 1542 self.match(PartiQLParser.FROM) - self.state = 1518 + self.state = 1543 self.expr() - self.state = 1521 + self.state = 1546 self._errHandler.sync(self) _la = self._input.LA(1) if _la==92: - self.state = 1519 + self.state = 1544 self.match(PartiQLParser.FOR) - self.state = 1520 + self.state = 1545 self.expr() - self.state = 1523 + self.state = 1548 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -13508,29 +13644,29 @@ def accept(self, visitor:ParseTreeVisitor): def aggregate(self): localctx = PartiQLParser.AggregateContext(self, self._ctx, self.state) - self.enterRule(localctx, 232, self.RULE_aggregate) + self.enterRule(localctx, 234, self.RULE_aggregate) self._la = 0 # Token type try: - self.state = 1539 + self.state = 1564 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,192,self._ctx) + la_ = self._interp.adaptivePredict(self._input,196,self._ctx) if la_ == 1: localctx = PartiQLParser.CountAllContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1527 + self.state = 1552 localctx.func = self.match(PartiQLParser.COUNT) - self.state = 1528 + self.state = 1553 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1529 + self.state = 1554 self.match(PartiQLParser.ASTERISK) - self.state = 1530 + self.state = 1555 self.match(PartiQLParser.PAREN_RIGHT) pass elif la_ == 2: localctx = PartiQLParser.AggregateBaseContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1531 + self.state = 1556 localctx.func = self._input.LT(1) _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 17592186077440) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 216172782113783809) != 0) or _la==189 or _la==196): @@ -13538,19 +13674,19 @@ def aggregate(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1532 + self.state = 1557 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1534 + self.state = 1559 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==67: - self.state = 1533 + self.state = 1558 self.setQuantifierStrategy() - self.state = 1536 + self.state = 1561 self.expr() - self.state = 1537 + self.state = 1562 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -13630,12 +13766,12 @@ def accept(self, visitor:ParseTreeVisitor): def windowFunction(self): localctx = PartiQLParser.WindowFunctionContext(self, self._ctx, self.state) - self.enterRule(localctx, 234, self.RULE_windowFunction) + self.enterRule(localctx, 236, self.RULE_windowFunction) self._la = 0 # Token type try: localctx = PartiQLParser.LagLeadFunctionContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1541 + self.state = 1566 localctx.func = self._input.LT(1) _la = self._input.LA(1) if not(_la==230 or _la==231): @@ -13643,33 +13779,33 @@ def windowFunction(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1542 + self.state = 1567 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1543 + self.state = 1568 self.expr() - self.state = 1550 + self.state = 1575 self._errHandler.sync(self) _la = self._input.LA(1) if _la==270: - self.state = 1544 + self.state = 1569 self.match(PartiQLParser.COMMA) - self.state = 1545 + self.state = 1570 self.expr() - self.state = 1548 + self.state = 1573 self._errHandler.sync(self) _la = self._input.LA(1) if _la==270: - self.state = 1546 + self.state = 1571 self.match(PartiQLParser.COMMA) - self.state = 1547 + self.state = 1572 self.expr() - self.state = 1552 + self.state = 1577 self.match(PartiQLParser.PAREN_RIGHT) - self.state = 1553 + self.state = 1578 self.over() except RecognitionException as re: localctx.exception = re @@ -13730,20 +13866,20 @@ def accept(self, visitor:ParseTreeVisitor): def cast(self): localctx = PartiQLParser.CastContext(self, self._ctx, self.state) - self.enterRule(localctx, 236, self.RULE_cast) + self.enterRule(localctx, 238, self.RULE_cast) try: self.enterOuterAlt(localctx, 1) - self.state = 1555 + self.state = 1580 self.match(PartiQLParser.CAST) - self.state = 1556 + self.state = 1581 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1557 + self.state = 1582 self.expr() - self.state = 1558 + self.state = 1583 self.match(PartiQLParser.AS) - self.state = 1559 + self.state = 1584 self.type_() - self.state = 1560 + self.state = 1585 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -13804,20 +13940,20 @@ def accept(self, visitor:ParseTreeVisitor): def canLosslessCast(self): localctx = PartiQLParser.CanLosslessCastContext(self, self._ctx, self.state) - self.enterRule(localctx, 238, self.RULE_canLosslessCast) + self.enterRule(localctx, 240, self.RULE_canLosslessCast) try: self.enterOuterAlt(localctx, 1) - self.state = 1562 + self.state = 1587 self.match(PartiQLParser.CAN_LOSSLESS_CAST) - self.state = 1563 + self.state = 1588 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1564 + self.state = 1589 self.expr() - self.state = 1565 + self.state = 1590 self.match(PartiQLParser.AS) - self.state = 1566 + self.state = 1591 self.type_() - self.state = 1567 + self.state = 1592 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -13878,20 +14014,20 @@ def accept(self, visitor:ParseTreeVisitor): def canCast(self): localctx = PartiQLParser.CanCastContext(self, self._ctx, self.state) - self.enterRule(localctx, 240, self.RULE_canCast) + self.enterRule(localctx, 242, self.RULE_canCast) try: self.enterOuterAlt(localctx, 1) - self.state = 1569 + self.state = 1594 self.match(PartiQLParser.CAN_CAST) - self.state = 1570 + self.state = 1595 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1571 + self.state = 1596 self.expr() - self.state = 1572 + self.state = 1597 self.match(PartiQLParser.AS) - self.state = 1573 + self.state = 1598 self.type_() - self.state = 1574 + self.state = 1599 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -13952,20 +14088,20 @@ def accept(self, visitor:ParseTreeVisitor): def extract(self): localctx = PartiQLParser.ExtractContext(self, self._ctx, self.state) - self.enterRule(localctx, 242, self.RULE_extract) + self.enterRule(localctx, 244, self.RULE_extract) try: self.enterOuterAlt(localctx, 1) - self.state = 1576 + self.state = 1601 self.match(PartiQLParser.EXTRACT) - self.state = 1577 + self.state = 1602 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1578 + self.state = 1603 self.match(PartiQLParser.IDENTIFIER) - self.state = 1579 + self.state = 1604 self.match(PartiQLParser.FROM) - self.state = 1580 + self.state = 1605 localctx.rhs = self.expr() - self.state = 1581 + self.state = 1606 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14032,41 +14168,41 @@ def accept(self, visitor:ParseTreeVisitor): def trimFunction(self): localctx = PartiQLParser.TrimFunctionContext(self, self._ctx, self.state) - self.enterRule(localctx, 244, self.RULE_trimFunction) + self.enterRule(localctx, 246, self.RULE_trimFunction) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1583 + self.state = 1608 localctx.func = self.match(PartiQLParser.TRIM) - self.state = 1584 + self.state = 1609 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1592 + self.state = 1617 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,197,self._ctx) + la_ = self._interp.adaptivePredict(self._input,201,self._ctx) if la_ == 1: - self.state = 1586 + self.state = 1611 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,195,self._ctx) + la_ = self._interp.adaptivePredict(self._input,199,self._ctx) if la_ == 1: - self.state = 1585 + self.state = 1610 localctx.mod = self.match(PartiQLParser.IDENTIFIER) - self.state = 1589 + self.state = 1614 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 11558071357178112) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 234187180623281297) != 0) or ((((_la - 140)) & ~0x3f) == 0 and ((1 << (_la - 140)) & 7026323504187375659) != 0) or ((((_la - 207)) & ~0x3f) == 0 and ((1 << (_la - 207)) & 1729382258948706371) != 0) or ((((_la - 271)) & ~0x3f) == 0 and ((1 << (_la - 271)) & 291666264083) != 0): - self.state = 1588 + self.state = 1613 localctx.sub = self.expr() - self.state = 1591 + self.state = 1616 self.match(PartiQLParser.FROM) - self.state = 1594 + self.state = 1619 localctx.target = self.expr() - self.state = 1595 + self.state = 1620 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14137,11 +14273,11 @@ def accept(self, visitor:ParseTreeVisitor): def dateFunction(self): localctx = PartiQLParser.DateFunctionContext(self, self._ctx, self.state) - self.enterRule(localctx, 246, self.RULE_dateFunction) + self.enterRule(localctx, 248, self.RULE_dateFunction) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1597 + self.state = 1622 localctx.func = self._input.LT(1) _la = self._input.LA(1) if not(_la==86 or _la==87): @@ -14149,19 +14285,19 @@ def dateFunction(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1598 + self.state = 1623 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1599 + self.state = 1624 localctx.dt = self.match(PartiQLParser.IDENTIFIER) - self.state = 1600 + self.state = 1625 self.match(PartiQLParser.COMMA) - self.state = 1601 + self.state = 1626 self.expr() - self.state = 1602 + self.state = 1627 self.match(PartiQLParser.COMMA) - self.state = 1603 + self.state = 1628 self.expr() - self.state = 1604 + self.state = 1629 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14225,35 +14361,35 @@ def accept(self, visitor:ParseTreeVisitor): def functionCall(self): localctx = PartiQLParser.FunctionCallContext(self, self._ctx, self.state) - self.enterRule(localctx, 248, self.RULE_functionCall) + self.enterRule(localctx, 250, self.RULE_functionCall) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1606 + self.state = 1631 self.functionName() - self.state = 1607 + self.state = 1632 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1616 + self.state = 1641 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 11558071357178112) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 234187180623281297) != 0) or ((((_la - 140)) & ~0x3f) == 0 and ((1 << (_la - 140)) & 7026323504187375659) != 0) or ((((_la - 207)) & ~0x3f) == 0 and ((1 << (_la - 207)) & 1729382258948706371) != 0) or ((((_la - 271)) & ~0x3f) == 0 and ((1 << (_la - 271)) & 291666264083) != 0): - self.state = 1608 + self.state = 1633 self.expr() - self.state = 1613 + self.state = 1638 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 1609 + self.state = 1634 self.match(PartiQLParser.COMMA) - self.state = 1610 + self.state = 1635 self.expr() - self.state = 1615 + self.state = 1640 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1618 + self.state = 1643 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14375,29 +14511,29 @@ def accept(self, visitor:ParseTreeVisitor): def functionName(self): localctx = PartiQLParser.FunctionNameContext(self, self._ctx, self.state) - self.enterRule(localctx, 250, self.RULE_functionName) + self.enterRule(localctx, 252, self.RULE_functionName) self._la = 0 # Token type try: - self.state = 1638 + self.state = 1663 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,202,self._ctx) + la_ = self._interp.adaptivePredict(self._input,206,self._ctx) if la_ == 1: localctx = PartiQLParser.FunctionNameReservedContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1625 + self.state = 1650 self._errHandler.sync(self) _la = self._input.LA(1) while _la==303 or _la==304: - self.state = 1620 + self.state = 1645 localctx._symbolPrimitive = self.symbolPrimitive() localctx.qualifier.append(localctx._symbolPrimitive) - self.state = 1621 + self.state = 1646 self.match(PartiQLParser.PERIOD) - self.state = 1627 + self.state = 1652 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1628 + self.state = 1653 localctx.name = self._input.LT(1) _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 17592991875072) != 0) or ((((_la - 82)) & ~0x3f) == 0 and ((1 << (_la - 82)) & -9223231299366420479) != 0) or _la==187 or _la==213): @@ -14410,21 +14546,21 @@ def functionName(self): elif la_ == 2: localctx = PartiQLParser.FunctionNameSymbolContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1634 + self.state = 1659 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,201,self._ctx) + _alt = self._interp.adaptivePredict(self._input,205,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 1629 + self.state = 1654 localctx._symbolPrimitive = self.symbolPrimitive() localctx.qualifier.append(localctx._symbolPrimitive) - self.state = 1630 + self.state = 1655 self.match(PartiQLParser.PERIOD) - self.state = 1636 + self.state = 1661 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,201,self._ctx) + _alt = self._interp.adaptivePredict(self._input,205,self._ctx) - self.state = 1637 + self.state = 1662 localctx.name = self.symbolPrimitive() pass @@ -14573,48 +14709,48 @@ def accept(self, visitor:ParseTreeVisitor): def pathStep(self): localctx = PartiQLParser.PathStepContext(self, self._ctx, self.state) - self.enterRule(localctx, 252, self.RULE_pathStep) + self.enterRule(localctx, 254, self.RULE_pathStep) try: - self.state = 1651 + self.state = 1676 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,203,self._ctx) + la_ = self._interp.adaptivePredict(self._input,207,self._ctx) if la_ == 1: localctx = PartiQLParser.PathStepIndexExprContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1640 + self.state = 1665 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 1641 + self.state = 1666 localctx.key = self.expr() - self.state = 1642 + self.state = 1667 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 2: localctx = PartiQLParser.PathStepIndexAllContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1644 + self.state = 1669 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 1645 + self.state = 1670 localctx.all_ = self.match(PartiQLParser.ASTERISK) - self.state = 1646 + self.state = 1671 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 3: localctx = PartiQLParser.PathStepDotExprContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1647 + self.state = 1672 self.match(PartiQLParser.PERIOD) - self.state = 1648 + self.state = 1673 localctx.key = self.symbolPrimitive() pass elif la_ == 4: localctx = PartiQLParser.PathStepDotAllContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 1649 + self.state = 1674 self.match(PartiQLParser.PERIOD) - self.state = 1650 + self.state = 1675 localctx.all_ = self.match(PartiQLParser.ASTERISK) pass @@ -14675,18 +14811,18 @@ def accept(self, visitor:ParseTreeVisitor): def exprGraphMatchMany(self): localctx = PartiQLParser.ExprGraphMatchManyContext(self, self._ctx, self.state) - self.enterRule(localctx, 254, self.RULE_exprGraphMatchMany) + self.enterRule(localctx, 256, self.RULE_exprGraphMatchMany) try: self.enterOuterAlt(localctx, 1) - self.state = 1653 + self.state = 1678 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1654 + self.state = 1679 self.exprPrimary(0) - self.state = 1655 + self.state = 1680 self.match(PartiQLParser.MATCH) - self.state = 1656 + self.state = 1681 self.gpmlPatternList() - self.state = 1657 + self.state = 1682 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14738,14 +14874,14 @@ def accept(self, visitor:ParseTreeVisitor): def exprGraphMatchOne(self): localctx = PartiQLParser.ExprGraphMatchOneContext(self, self._ctx, self.state) - self.enterRule(localctx, 256, self.RULE_exprGraphMatchOne) + self.enterRule(localctx, 258, self.RULE_exprGraphMatchOne) try: self.enterOuterAlt(localctx, 1) - self.state = 1659 + self.state = 1684 self.exprPrimary(0) - self.state = 1660 + self.state = 1685 self.match(PartiQLParser.MATCH) - self.state = 1661 + self.state = 1686 self.gpmlPattern() except RecognitionException as re: localctx.exception = re @@ -14789,10 +14925,10 @@ def accept(self, visitor:ParseTreeVisitor): def parameter(self): localctx = PartiQLParser.ParameterContext(self, self._ctx, self.state) - self.enterRule(localctx, 258, self.RULE_parameter) + self.enterRule(localctx, 260, self.RULE_parameter) try: self.enterOuterAlt(localctx, 1) - self.state = 1663 + self.state = 1688 self.match(PartiQLParser.QUESTION_MARK) except RecognitionException as re: localctx.exception = re @@ -14883,24 +15019,24 @@ def accept(self, visitor:ParseTreeVisitor): def varRefExpr(self): localctx = PartiQLParser.VarRefExprContext(self, self._ctx, self.state) - self.enterRule(localctx, 260, self.RULE_varRefExpr) + self.enterRule(localctx, 262, self.RULE_varRefExpr) self._la = 0 # Token type try: - self.state = 1673 + self.state = 1698 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,206,self._ctx) + la_ = self._interp.adaptivePredict(self._input,210,self._ctx) if la_ == 1: localctx = PartiQLParser.VariableIdentifierContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1666 + self.state = 1691 self._errHandler.sync(self) _la = self._input.LA(1) if _la==275: - self.state = 1665 + self.state = 1690 localctx.qualifier = self.match(PartiQLParser.AT_SIGN) - self.state = 1668 + self.state = 1693 localctx.ident = self._input.LT(1) _la = self._input.LA(1) if not(_la==303 or _la==304): @@ -14913,15 +15049,15 @@ def varRefExpr(self): elif la_ == 2: localctx = PartiQLParser.VariableKeywordContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1670 + self.state = 1695 self._errHandler.sync(self) _la = self._input.LA(1) if _la==275: - self.state = 1669 + self.state = 1694 localctx.qualifier = self.match(PartiQLParser.AT_SIGN) - self.state = 1672 + self.state = 1697 localctx.key = self.nonReservedKeywords() pass @@ -14968,10 +15104,10 @@ def accept(self, visitor:ParseTreeVisitor): def nonReservedKeywords(self): localctx = PartiQLParser.NonReservedKeywordsContext(self, self._ctx, self.state) - self.enterRule(localctx, 262, self.RULE_nonReservedKeywords) + self.enterRule(localctx, 264, self.RULE_nonReservedKeywords) try: self.enterOuterAlt(localctx, 1) - self.state = 1675 + self.state = 1700 self.match(PartiQLParser.EXCLUDED) except RecognitionException as re: localctx.exception = re @@ -15020,19 +15156,19 @@ def accept(self, visitor:ParseTreeVisitor): def collection(self): localctx = PartiQLParser.CollectionContext(self, self._ctx, self.state) - self.enterRule(localctx, 264, self.RULE_collection) + self.enterRule(localctx, 266, self.RULE_collection) try: - self.state = 1679 + self.state = 1704 self._errHandler.sync(self) token = self._input.LA(1) if token in [290]: self.enterOuterAlt(localctx, 1) - self.state = 1677 + self.state = 1702 self.array() pass elif token in [288]: self.enterOuterAlt(localctx, 2) - self.state = 1678 + self.state = 1703 self.bag() pass else: @@ -15096,33 +15232,33 @@ def accept(self, visitor:ParseTreeVisitor): def array(self): localctx = PartiQLParser.ArrayContext(self, self._ctx, self.state) - self.enterRule(localctx, 266, self.RULE_array) + self.enterRule(localctx, 268, self.RULE_array) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1681 + self.state = 1706 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 1690 + self.state = 1715 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 11558071357178112) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 234187180623281297) != 0) or ((((_la - 140)) & ~0x3f) == 0 and ((1 << (_la - 140)) & 7026323504187375659) != 0) or ((((_la - 207)) & ~0x3f) == 0 and ((1 << (_la - 207)) & 1729382258948706371) != 0) or ((((_la - 271)) & ~0x3f) == 0 and ((1 << (_la - 271)) & 291666264083) != 0): - self.state = 1682 + self.state = 1707 self.expr() - self.state = 1687 + self.state = 1712 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 1683 + self.state = 1708 self.match(PartiQLParser.COMMA) - self.state = 1684 + self.state = 1709 self.expr() - self.state = 1689 + self.state = 1714 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1692 + self.state = 1717 self.match(PartiQLParser.BRACKET_RIGHT) except RecognitionException as re: localctx.exception = re @@ -15182,33 +15318,33 @@ def accept(self, visitor:ParseTreeVisitor): def bag(self): localctx = PartiQLParser.BagContext(self, self._ctx, self.state) - self.enterRule(localctx, 268, self.RULE_bag) + self.enterRule(localctx, 270, self.RULE_bag) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1694 + self.state = 1719 self.match(PartiQLParser.ANGLE_DOUBLE_LEFT) - self.state = 1703 + self.state = 1728 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 11558071357178112) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 234187180623281297) != 0) or ((((_la - 140)) & ~0x3f) == 0 and ((1 << (_la - 140)) & 7026323504187375659) != 0) or ((((_la - 207)) & ~0x3f) == 0 and ((1 << (_la - 207)) & 1729382258948706371) != 0) or ((((_la - 271)) & ~0x3f) == 0 and ((1 << (_la - 271)) & 291666264083) != 0): - self.state = 1695 + self.state = 1720 self.expr() - self.state = 1700 + self.state = 1725 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 1696 + self.state = 1721 self.match(PartiQLParser.COMMA) - self.state = 1697 + self.state = 1722 self.expr() - self.state = 1702 + self.state = 1727 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1705 + self.state = 1730 self.match(PartiQLParser.ANGLE_DOUBLE_RIGHT) except RecognitionException as re: localctx.exception = re @@ -15268,33 +15404,33 @@ def accept(self, visitor:ParseTreeVisitor): def tuple_(self): localctx = PartiQLParser.TupleContext(self, self._ctx, self.state) - self.enterRule(localctx, 270, self.RULE_tuple) + self.enterRule(localctx, 272, self.RULE_tuple) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1707 + self.state = 1732 self.match(PartiQLParser.BRACE_LEFT) - self.state = 1716 + self.state = 1741 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 11558071357178112) != 0) or ((((_la - 75)) & ~0x3f) == 0 and ((1 << (_la - 75)) & 234187180623281297) != 0) or ((((_la - 140)) & ~0x3f) == 0 and ((1 << (_la - 140)) & 7026323504187375659) != 0) or ((((_la - 207)) & ~0x3f) == 0 and ((1 << (_la - 207)) & 1729382258948706371) != 0) or ((((_la - 271)) & ~0x3f) == 0 and ((1 << (_la - 271)) & 291666264083) != 0): - self.state = 1708 + self.state = 1733 self.pair() - self.state = 1713 + self.state = 1738 self._errHandler.sync(self) _la = self._input.LA(1) while _la==270: - self.state = 1709 + self.state = 1734 self.match(PartiQLParser.COMMA) - self.state = 1710 + self.state = 1735 self.pair() - self.state = 1715 + self.state = 1740 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1718 + self.state = 1743 self.match(PartiQLParser.BRACE_RIGHT) except RecognitionException as re: localctx.exception = re @@ -15347,14 +15483,14 @@ def accept(self, visitor:ParseTreeVisitor): def pair(self): localctx = PartiQLParser.PairContext(self, self._ctx, self.state) - self.enterRule(localctx, 272, self.RULE_pair) + self.enterRule(localctx, 274, self.RULE_pair) try: self.enterOuterAlt(localctx, 1) - self.state = 1720 + self.state = 1745 localctx.lhs = self.expr() - self.state = 1721 + self.state = 1746 self.match(PartiQLParser.COLON) - self.state = 1722 + self.state = 1747 localctx.rhs = self.expr() except RecognitionException as re: localctx.exception = re @@ -15681,130 +15817,130 @@ def accept(self, visitor:ParseTreeVisitor): def literal(self): localctx = PartiQLParser.LiteralContext(self, self._ctx, self.state) - self.enterRule(localctx, 274, self.RULE_literal) + self.enterRule(localctx, 276, self.RULE_literal) self._la = 0 # Token type try: - self.state = 1758 + self.state = 1783 self._errHandler.sync(self) token = self._input.LA(1) if token in [141]: localctx = PartiQLParser.LiteralNullContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1724 + self.state = 1749 self.match(PartiQLParser.NULL) pass elif token in [236]: localctx = PartiQLParser.LiteralMissingContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1725 + self.state = 1750 self.match(PartiQLParser.MISSING) pass elif token in [208]: localctx = PartiQLParser.LiteralTrueContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1726 + self.state = 1751 self.match(PartiQLParser.TRUE) pass elif token in [88]: localctx = PartiQLParser.LiteralFalseContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 1727 + self.state = 1752 self.match(PartiQLParser.FALSE) pass elif token in [300]: localctx = PartiQLParser.LiteralStringContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 1728 + self.state = 1753 self.match(PartiQLParser.LITERAL_STRING) pass elif token in [301]: localctx = PartiQLParser.LiteralIntegerContext(self, localctx) self.enterOuterAlt(localctx, 6) - self.state = 1729 + self.state = 1754 self.match(PartiQLParser.LITERAL_INTEGER) pass elif token in [302]: localctx = PartiQLParser.LiteralDecimalContext(self, localctx) self.enterOuterAlt(localctx, 7) - self.state = 1730 + self.state = 1755 self.match(PartiQLParser.LITERAL_DECIMAL) pass elif token in [309]: localctx = PartiQLParser.LiteralIonContext(self, localctx) self.enterOuterAlt(localctx, 8) - self.state = 1731 + self.state = 1756 self.match(PartiQLParser.ION_CLOSURE) pass elif token in [53]: localctx = PartiQLParser.LiteralDateContext(self, localctx) self.enterOuterAlt(localctx, 9) - self.state = 1732 + self.state = 1757 self.match(PartiQLParser.DATE) - self.state = 1733 + self.state = 1758 self.match(PartiQLParser.LITERAL_STRING) pass elif token in [201]: localctx = PartiQLParser.LiteralTimeContext(self, localctx) self.enterOuterAlt(localctx, 10) - self.state = 1734 + self.state = 1759 self.match(PartiQLParser.TIME) - self.state = 1738 + self.state = 1763 self._errHandler.sync(self) _la = self._input.LA(1) if _la==294: - self.state = 1735 + self.state = 1760 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1736 + self.state = 1761 self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1737 + self.state = 1762 self.match(PartiQLParser.PAREN_RIGHT) - self.state = 1743 + self.state = 1768 self._errHandler.sync(self) _la = self._input.LA(1) if _la==226: - self.state = 1740 + self.state = 1765 self.match(PartiQLParser.WITH) - self.state = 1741 + self.state = 1766 self.match(PartiQLParser.TIME) - self.state = 1742 + self.state = 1767 self.match(PartiQLParser.ZONE) - self.state = 1745 + self.state = 1770 self.match(PartiQLParser.LITERAL_STRING) pass elif token in [202]: localctx = PartiQLParser.LiteralTimestampContext(self, localctx) self.enterOuterAlt(localctx, 11) - self.state = 1746 + self.state = 1771 self.match(PartiQLParser.TIMESTAMP) - self.state = 1750 + self.state = 1775 self._errHandler.sync(self) _la = self._input.LA(1) if _la==294: - self.state = 1747 + self.state = 1772 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1748 + self.state = 1773 self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1749 + self.state = 1774 self.match(PartiQLParser.PAREN_RIGHT) - self.state = 1755 + self.state = 1780 self._errHandler.sync(self) _la = self._input.LA(1) if _la==226: - self.state = 1752 + self.state = 1777 self.match(PartiQLParser.WITH) - self.state = 1753 + self.state = 1778 self.match(PartiQLParser.TIME) - self.state = 1754 + self.state = 1779 self.match(PartiQLParser.ZONE) - self.state = 1757 + self.state = 1782 self.match(PartiQLParser.LITERAL_STRING) pass else: @@ -16102,16 +16238,16 @@ def accept(self, visitor:ParseTreeVisitor): def type_(self): localctx = PartiQLParser.TypeContext(self, self._ctx, self.state) - self.enterRule(localctx, 276, self.RULE_type) + self.enterRule(localctx, 278, self.RULE_type) self._la = 0 # Token type try: - self.state = 1798 + self.state = 1823 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,225,self._ctx) + la_ = self._interp.adaptivePredict(self._input,229,self._ctx) if la_ == 1: localctx = PartiQLParser.TypeAtomicContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1760 + self.state = 1785 localctx.datatype = self._input.LT(1) _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 9007199456067840) != 0) or ((((_la - 113)) & ~0x3f) == 0 and ((1 << (_la - 113)) & 144115188344291331) != 0) or ((((_la - 188)) & ~0x3f) == 0 and ((1 << (_la - 188)) & -9223090561878065151) != 0) or ((((_la - 252)) & ~0x3f) == 0 and ((1 << (_la - 252)) & 131071) != 0)): @@ -16124,16 +16260,16 @@ def type_(self): elif la_ == 2: localctx = PartiQLParser.TypeAtomicContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1761 + self.state = 1786 localctx.datatype = self.match(PartiQLParser.DOUBLE) - self.state = 1762 + self.state = 1787 self.match(PartiQLParser.PRECISION) pass elif la_ == 3: localctx = PartiQLParser.TypeArgSingleContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1763 + self.state = 1788 localctx.datatype = self._input.LT(1) _la = self._input.LA(1) if not(_la==26 or _la==27 or _la==91 or _la==220): @@ -16141,15 +16277,15 @@ def type_(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1767 + self.state = 1792 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,219,self._ctx) + la_ = self._interp.adaptivePredict(self._input,223,self._ctx) if la_ == 1: - self.state = 1764 + self.state = 1789 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1765 + self.state = 1790 localctx.arg0 = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1766 + self.state = 1791 self.match(PartiQLParser.PAREN_RIGHT) @@ -16158,19 +16294,19 @@ def type_(self): elif la_ == 4: localctx = PartiQLParser.TypeVarCharContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 1769 + self.state = 1794 self.match(PartiQLParser.CHARACTER) - self.state = 1770 + self.state = 1795 self.match(PartiQLParser.VARYING) - self.state = 1774 + self.state = 1799 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,220,self._ctx) + la_ = self._interp.adaptivePredict(self._input,224,self._ctx) if la_ == 1: - self.state = 1771 + self.state = 1796 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1772 + self.state = 1797 localctx.arg0 = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1773 + self.state = 1798 self.match(PartiQLParser.PAREN_RIGHT) @@ -16179,7 +16315,7 @@ def type_(self): elif la_ == 5: localctx = PartiQLParser.TypeArgDoubleContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 1776 + self.state = 1801 localctx.datatype = self._input.LT(1) _la = self._input.LA(1) if not(_la==55 or _la==56 or _la==144): @@ -16187,25 +16323,25 @@ def type_(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1784 + self.state = 1809 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,222,self._ctx) + la_ = self._interp.adaptivePredict(self._input,226,self._ctx) if la_ == 1: - self.state = 1777 + self.state = 1802 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1778 + self.state = 1803 localctx.arg0 = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1781 + self.state = 1806 self._errHandler.sync(self) _la = self._input.LA(1) if _la==270: - self.state = 1779 + self.state = 1804 self.match(PartiQLParser.COMMA) - self.state = 1780 + self.state = 1805 localctx.arg1 = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1783 + self.state = 1808 self.match(PartiQLParser.PAREN_RIGHT) @@ -16214,7 +16350,7 @@ def type_(self): elif la_ == 6: localctx = PartiQLParser.TypeTimeZoneContext(self, localctx) self.enterOuterAlt(localctx, 6) - self.state = 1786 + self.state = 1811 localctx.datatype = self._input.LT(1) _la = self._input.LA(1) if not(_la==201 or _la==202): @@ -16222,27 +16358,27 @@ def type_(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1790 + self.state = 1815 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,223,self._ctx) + la_ = self._interp.adaptivePredict(self._input,227,self._ctx) if la_ == 1: - self.state = 1787 + self.state = 1812 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1788 + self.state = 1813 localctx.precision = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1789 + self.state = 1814 self.match(PartiQLParser.PAREN_RIGHT) - self.state = 1795 + self.state = 1820 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,224,self._ctx) + la_ = self._interp.adaptivePredict(self._input,228,self._ctx) if la_ == 1: - self.state = 1792 + self.state = 1817 self.match(PartiQLParser.WITH) - self.state = 1793 + self.state = 1818 self.match(PartiQLParser.TIME) - self.state = 1794 + self.state = 1819 self.match(PartiQLParser.ZONE) @@ -16251,7 +16387,7 @@ def type_(self): elif la_ == 7: localctx = PartiQLParser.TypeCustomContext(self, localctx) self.enterOuterAlt(localctx, 7) - self.state = 1797 + self.state = 1822 self.symbolPrimitive() pass @@ -16269,17 +16405,17 @@ def type_(self): def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): if self._predicates == None: self._predicates = dict() - self._predicates[81] = self.labelSpec_sempred - self._predicates[82] = self.labelTerm_sempred - self._predicates[86] = self.tableReference_sempred - self._predicates[94] = self.exprBagOp_sempred - self._predicates[96] = self.exprOr_sempred - self._predicates[97] = self.exprAnd_sempred - self._predicates[99] = self.exprPredicate_sempred - self._predicates[100] = self.mathOp00_sempred - self._predicates[101] = self.mathOp01_sempred - self._predicates[102] = self.mathOp02_sempred - self._predicates[104] = self.exprPrimary_sempred + self._predicates[82] = self.labelSpec_sempred + self._predicates[83] = self.labelTerm_sempred + self._predicates[87] = self.tableReference_sempred + self._predicates[95] = self.exprBagOp_sempred + self._predicates[97] = self.exprOr_sempred + self._predicates[98] = self.exprAnd_sempred + self._predicates[100] = self.exprPredicate_sempred + self._predicates[101] = self.mathOp00_sempred + self._predicates[102] = self.mathOp01_sempred + self._predicates[103] = self.mathOp02_sempred + self._predicates[105] = self.exprPrimary_sempred pred = self._predicates.get(ruleIndex, None) if pred is None: raise Exception("No predicate with index:" + str(ruleIndex)) diff --git a/pymongosql/sql/partiql/PartiQLParserListener.py b/pymongosql/sql/partiql/PartiQLParserListener.py index a9b5fbf..8ea0a39 100644 --- a/pymongosql/sql/partiql/PartiQLParserListener.py +++ b/pymongosql/sql/partiql/PartiQLParserListener.py @@ -377,6 +377,15 @@ def exitInsertStatement(self, ctx:PartiQLParser.InsertStatementContext): pass + # Enter a parse tree produced by PartiQLParser#columnList. + def enterColumnList(self, ctx:PartiQLParser.ColumnListContext): + pass + + # Exit a parse tree produced by PartiQLParser#columnList. + def exitColumnList(self, ctx:PartiQLParser.ColumnListContext): + pass + + # Enter a parse tree produced by PartiQLParser#onConflict. def enterOnConflict(self, ctx:PartiQLParser.OnConflictContext): pass diff --git a/pymongosql/sql/partiql/PartiQLParserVisitor.py b/pymongosql/sql/partiql/PartiQLParserVisitor.py index ebc3854..6ed03a4 100644 --- a/pymongosql/sql/partiql/PartiQLParserVisitor.py +++ b/pymongosql/sql/partiql/PartiQLParserVisitor.py @@ -214,6 +214,11 @@ def visitInsertStatement(self, ctx:PartiQLParser.InsertStatementContext): return self.visitChildren(ctx) + # Visit a parse tree produced by PartiQLParser#columnList. + def visitColumnList(self, ctx:PartiQLParser.ColumnListContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by PartiQLParser#onConflict. def visitOnConflict(self, ctx:PartiQLParser.OnConflictContext): return self.visitChildren(ctx) From 3f630cd10bca5f0c4d619998adac99082297f2c8 Mon Sep 17 00:00:00 2001 From: Peng Ren Date: Tue, 30 Dec 2025 16:40:39 -0500 Subject: [PATCH 3/5] Added classic insert statement with column list and works in SQLAlchemy --- pymongosql/sql/ast.py | 21 +- pymongosql/sql/insert_handler.py | 142 +++- pymongosql/sql/partiql/PartiQLLexer.py | 4 +- pymongosql/sql/partiql/PartiQLParser.g4 | 4 +- pymongosql/sql/partiql/PartiQLParser.py | 62 +- .../sql/partiql/PartiQLParserListener.py | 2 +- .../sql/partiql/PartiQLParserVisitor.py | 2 +- tests/conftest.py | 76 ++ tests/test_cursor_insert.py | 16 + tests/test_sql_parser_insert.py | 48 -- tests/test_sql_parser_insert_values.py | 146 ++++ tests/test_sqlalchemy_dml.py | 678 ++++++++++++++++++ ...ntegration.py => test_sqlalchemy_query.py} | 95 +-- 13 files changed, 1125 insertions(+), 171 deletions(-) create mode 100644 tests/test_sql_parser_insert_values.py create mode 100644 tests/test_sqlalchemy_dml.py rename tests/{test_sqlalchemy_integration.py => test_sqlalchemy_query.py} (79%) diff --git a/pymongosql/sql/ast.py b/pymongosql/sql/ast.py index e95e458..0ab473b 100644 --- a/pymongosql/sql/ast.py +++ b/pymongosql/sql/ast.py @@ -137,7 +137,10 @@ def visitInsertStatement(self, ctx: PartiQLParser.InsertStatementContext) -> Any self._insert_parse_result = InsertParseResult.for_visitor() handler = self._handlers.get("insert") if handler: - return handler.handle_visitor(ctx, self._insert_parse_result) + handler.handle_visitor(ctx, self._insert_parse_result) + # Continue visiting children to process columnList and values + self.visitChildren(ctx) + return self._insert_parse_result return self.visitChildren(ctx) def visitInsertStatementLegacy(self, ctx: PartiQLParser.InsertStatementLegacyContext) -> Any: @@ -151,6 +154,22 @@ def visitInsertStatementLegacy(self, ctx: PartiQLParser.InsertStatementLegacyCon return handler.handle_visitor(ctx, self._insert_parse_result) return self.visitChildren(ctx) + def visitColumnList(self, ctx: PartiQLParser.ColumnListContext) -> Any: + """Handle column list in INSERT statements.""" + if self._current_operation == "insert": + handler = self._handlers.get("insert") + if handler: + return handler.handle_column_list(ctx, self._insert_parse_result) + return self.visitChildren(ctx) + + def visitValues(self, ctx: PartiQLParser.ValuesContext) -> Any: + """Handle VALUES clause in INSERT statements.""" + if self._current_operation == "insert": + handler = self._handlers.get("insert") + if handler: + return handler.handle_values(ctx, self._insert_parse_result) + return self.visitChildren(ctx) + def visitFromClauseSimpleExplicit(self, ctx: PartiQLParser.FromClauseSimpleExplicitContext) -> Any: """Handle FROM clause (explicit form) in DELETE statements.""" if self._current_operation == "delete": diff --git a/pymongosql/sql/insert_handler.py b/pymongosql/sql/insert_handler.py index 09b6ae0..1d2a76f 100644 --- a/pymongosql/sql/insert_handler.py +++ b/pymongosql/sql/insert_handler.py @@ -39,8 +39,17 @@ def can_handle(self, ctx: Any) -> bool: def handle_visitor(self, ctx: Any, parse_result: InsertParseResult) -> InsertParseResult: try: collection = self._extract_collection(ctx) - value_text = self._extract_value_text(ctx) + # Check if this is a VALUES clause INSERT (new syntax) + if hasattr(ctx, "values") and ctx.values(): + _logger.debug("Processing INSERT with VALUES clause") + parse_result.collection = collection + parse_result.insert_type = "values" + # Return parse_result - visitor will call handle_column_list and handle_values + return parse_result + + # Otherwise, handle legacy value expression INSERT + value_text = self._extract_value_text(ctx) documents = self._parse_value_expr(value_text) param_style, param_count = self._detect_parameter_style(documents) @@ -58,6 +67,137 @@ def handle_visitor(self, ctx: Any, parse_result: InsertParseResult) -> InsertPar parse_result.error_message = str(exc) return parse_result + def handle_column_list(self, ctx: Any, parse_result: InsertParseResult) -> Optional[List[str]]: + """Extract column names from columnList context.""" + _logger.debug("InsertHandler processing column list") + try: + columns = [] + column_names = ctx.columnName() + if column_names: + if not isinstance(column_names, list): + column_names = [column_names] + for col_name_ctx in column_names: + # columnName contains a symbolPrimitive + symbol = col_name_ctx.symbolPrimitive() + if symbol: + columns.append(symbol.getText()) + parse_result.insert_columns = columns + _logger.debug(f"Extracted columns for INSERT: {columns}") + return columns + except Exception as e: + _logger.warning(f"Error processing column list: {e}") + parse_result.has_errors = True + parse_result.error_message = str(e) + return None + + def handle_values(self, ctx: Any, parse_result: InsertParseResult) -> Optional[List[List[Any]]]: + """Extract value rows from VALUES clause.""" + _logger.debug("InsertHandler processing VALUES clause") + try: + rows = [] + value_rows = ctx.valueRow() + if value_rows: + if not isinstance(value_rows, list): + value_rows = [value_rows] + for value_row_ctx in value_rows: + row_values = self._extract_value_row(value_row_ctx) + rows.append(row_values) + + parse_result.insert_values = rows + + # Convert rows to documents + columns = parse_result.insert_columns + documents = self._convert_rows_to_documents(columns, rows) + parse_result.insert_documents = documents + + # Detect parameter style + param_style, param_count = self._detect_parameter_style(documents) + parse_result.parameter_style = param_style + parse_result.parameter_count = param_count + parse_result.has_errors = False + parse_result.error_message = None + + _logger.debug(f"Extracted {len(rows)} value rows for INSERT") + return rows + except Exception as e: + _logger.warning(f"Error processing VALUES clause: {e}") + parse_result.has_errors = True + parse_result.error_message = str(e) + return None + + def _extract_value_row(self, value_row_ctx: Any) -> List[Any]: + """Extract values from a single valueRow.""" + row_values = [] + exprs = value_row_ctx.expr() + if exprs: + if not isinstance(exprs, list): + exprs = [exprs] + for expr_ctx in exprs: + value = self._parse_expression_value(expr_ctx) + row_values.append(value) + return row_values + + def _parse_expression_value(self, expr_ctx: Any) -> Any: + """Parse a single expression value from the parse tree.""" + if not expr_ctx: + return None + + text = expr_ctx.getText() + + # Handle NULL + if text.upper() == "NULL": + return None + + # Handle boolean literals + if text.upper() == "TRUE": + return True + if text.upper() == "FALSE": + return False + + # Handle string literals (quoted) + if (text.startswith("'") and text.endswith("'")) or (text.startswith('"') and text.endswith('"')): + return text[1:-1] + + # Handle numeric literals + try: + if "." in text: + return float(text) + return int(text) + except ValueError: + pass + + # Handle parameters (? or :name) + if text == "?": + return "?" + if text.startswith(":"): + return text + + # For complex expressions, return as-is + return text + + def _convert_rows_to_documents(self, columns: Optional[List[str]], rows: List[List[Any]]) -> List[Dict[str, Any]]: + """Convert rows to MongoDB documents.""" + documents = [] + + for row in rows: + doc = {} + + if columns: + # Use explicit column names + if len(row) != len(columns): + raise ValueError(f"Column count ({len(columns)}) does not match value count ({len(row)})") + + for col, val in zip(columns, row): + doc[col] = val + else: + # Generate automatic column names (col0, col1, ...) + for idx, val in enumerate(row): + doc[f"col{idx}"] = val + + documents.append(doc) + + return documents + def _extract_collection(self, ctx: Any) -> str: if hasattr(ctx, "symbolPrimitive") and ctx.symbolPrimitive(): return ctx.symbolPrimitive().getText() diff --git a/pymongosql/sql/partiql/PartiQLLexer.py b/pymongosql/sql/partiql/PartiQLLexer.py index acfb306..de06d41 100644 --- a/pymongosql/sql/partiql/PartiQLLexer.py +++ b/pymongosql/sql/partiql/PartiQLLexer.py @@ -1,4 +1,4 @@ -# Generated from PartiQLLexer.g4 by ANTLR 4.13.2 +# Generated from PartiQLLexer.g4 by ANTLR 4.13.0 from antlr4 import * from io import StringIO import sys @@ -1678,7 +1678,7 @@ class PartiQLLexer(Lexer): def __init__(self, input=None, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.2") + self.checkVersion("4.13.0") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/pymongosql/sql/partiql/PartiQLParser.g4 b/pymongosql/sql/partiql/PartiQLParser.g4 index bc8328a..61b0417 100644 --- a/pymongosql/sql/partiql/PartiQLParser.g4 +++ b/pymongosql/sql/partiql/PartiQLParser.g4 @@ -166,8 +166,8 @@ insertCommandReturning // See the Grammar at https://github.com/partiql/partiql-docs/blob/main/RFCs/0011-partiql-insert.md#2-proposed-grammar-and-semantics insertStatement - : INSERT INTO symbolPrimitive asIdent? value=expr onConflict? - | INSERT INTO symbolPrimitive columnList? values onConflict? + : INSERT INTO symbolPrimitive columnList? values onConflict? + | INSERT INTO symbolPrimitive asIdent? value=expr onConflict? ; columnList diff --git a/pymongosql/sql/partiql/PartiQLParser.py b/pymongosql/sql/partiql/PartiQLParser.py index 8fbef32..38e260b 100644 --- a/pymongosql/sql/partiql/PartiQLParser.py +++ b/pymongosql/sql/partiql/PartiQLParser.py @@ -1,4 +1,4 @@ -# Generated from PartiQLParser.g4 by ANTLR 4.13.2 +# Generated from PartiQLParser.g4 by ANTLR 4.13.0 # encoding: utf-8 from antlr4 import * from io import StringIO @@ -303,21 +303,21 @@ def serializedATN(): 513,511,1,0,0,0,513,514,1,0,0,0,514,516,1,0,0,0,515,517,3,66,33, 0,516,515,1,0,0,0,516,517,1,0,0,0,517,519,1,0,0,0,518,520,3,86,43, 0,519,518,1,0,0,0,519,520,1,0,0,0,520,57,1,0,0,0,521,522,5,112,0, - 0,522,523,5,117,0,0,523,525,3,12,6,0,524,526,3,6,3,0,525,524,1,0, - 0,0,525,526,1,0,0,0,526,527,1,0,0,0,527,529,3,188,94,0,528,530,3, - 62,31,0,529,528,1,0,0,0,529,530,1,0,0,0,530,542,1,0,0,0,531,532, - 5,112,0,0,532,533,5,117,0,0,533,535,3,12,6,0,534,536,3,60,30,0,535, - 534,1,0,0,0,535,536,1,0,0,0,536,537,1,0,0,0,537,539,3,220,110,0, - 538,540,3,62,31,0,539,538,1,0,0,0,539,540,1,0,0,0,540,542,1,0,0, - 0,541,521,1,0,0,0,541,531,1,0,0,0,542,59,1,0,0,0,543,544,5,294,0, - 0,544,549,3,24,12,0,545,546,5,270,0,0,546,548,3,24,12,0,547,545, - 1,0,0,0,548,551,1,0,0,0,549,547,1,0,0,0,549,550,1,0,0,0,550,552, - 1,0,0,0,551,549,1,0,0,0,552,553,5,295,0,0,553,61,1,0,0,0,554,555, - 5,147,0,0,555,557,5,244,0,0,556,558,3,68,34,0,557,556,1,0,0,0,557, - 558,1,0,0,0,558,559,1,0,0,0,559,560,3,72,36,0,560,63,1,0,0,0,561, - 562,5,112,0,0,562,563,5,117,0,0,563,564,3,46,23,0,564,565,5,218, - 0,0,565,568,3,188,94,0,566,567,5,13,0,0,567,569,3,188,94,0,568,566, - 1,0,0,0,568,569,1,0,0,0,569,571,1,0,0,0,570,572,3,66,33,0,571,570, + 0,522,523,5,117,0,0,523,525,3,12,6,0,524,526,3,60,30,0,525,524,1, + 0,0,0,525,526,1,0,0,0,526,527,1,0,0,0,527,529,3,220,110,0,528,530, + 3,62,31,0,529,528,1,0,0,0,529,530,1,0,0,0,530,542,1,0,0,0,531,532, + 5,112,0,0,532,533,5,117,0,0,533,535,3,12,6,0,534,536,3,6,3,0,535, + 534,1,0,0,0,535,536,1,0,0,0,536,537,1,0,0,0,537,539,3,188,94,0,538, + 540,3,62,31,0,539,538,1,0,0,0,539,540,1,0,0,0,540,542,1,0,0,0,541, + 521,1,0,0,0,541,531,1,0,0,0,542,59,1,0,0,0,543,544,5,294,0,0,544, + 549,3,24,12,0,545,546,5,270,0,0,546,548,3,24,12,0,547,545,1,0,0, + 0,548,551,1,0,0,0,549,547,1,0,0,0,549,550,1,0,0,0,550,552,1,0,0, + 0,551,549,1,0,0,0,552,553,5,295,0,0,553,61,1,0,0,0,554,555,5,147, + 0,0,555,557,5,244,0,0,556,558,3,68,34,0,557,556,1,0,0,0,557,558, + 1,0,0,0,558,559,1,0,0,0,559,560,3,72,36,0,560,63,1,0,0,0,561,562, + 5,112,0,0,562,563,5,117,0,0,563,564,3,46,23,0,564,565,5,218,0,0, + 565,568,3,188,94,0,566,567,5,13,0,0,567,569,3,188,94,0,568,566,1, + 0,0,0,568,569,1,0,0,0,569,571,1,0,0,0,570,572,3,66,33,0,571,570, 1,0,0,0,571,572,1,0,0,0,572,65,1,0,0,0,573,574,5,147,0,0,574,575, 5,244,0,0,575,576,5,225,0,0,576,577,3,188,94,0,577,578,5,245,0,0, 578,579,5,250,0,0,579,67,1,0,0,0,580,581,5,294,0,0,581,586,3,12, @@ -1384,7 +1384,7 @@ class PartiQLParser ( Parser ): def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.2") + self.checkVersion("4.13.0") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None @@ -3969,24 +3969,24 @@ def symbolPrimitive(self): return self.getTypedRuleContext(PartiQLParser.SymbolPrimitiveContext,0) - def expr(self): - return self.getTypedRuleContext(PartiQLParser.ExprContext,0) + def values(self): + return self.getTypedRuleContext(PartiQLParser.ValuesContext,0) - def asIdent(self): - return self.getTypedRuleContext(PartiQLParser.AsIdentContext,0) + def columnList(self): + return self.getTypedRuleContext(PartiQLParser.ColumnListContext,0) def onConflict(self): return self.getTypedRuleContext(PartiQLParser.OnConflictContext,0) - def values(self): - return self.getTypedRuleContext(PartiQLParser.ValuesContext,0) + def expr(self): + return self.getTypedRuleContext(PartiQLParser.ExprContext,0) - def columnList(self): - return self.getTypedRuleContext(PartiQLParser.ColumnListContext,0) + def asIdent(self): + return self.getTypedRuleContext(PartiQLParser.AsIdentContext,0) def getRuleIndex(self): @@ -4029,13 +4029,13 @@ def insertStatement(self): self.state = 525 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==10: + if _la==294: self.state = 524 - self.asIdent() + self.columnList() self.state = 527 - localctx.value = self.expr() + self.values() self.state = 529 self._errHandler.sync(self) _la = self._input.LA(1) @@ -4057,13 +4057,13 @@ def insertStatement(self): self.state = 535 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==294: + if _la==10: self.state = 534 - self.columnList() + self.asIdent() self.state = 537 - self.values() + localctx.value = self.expr() self.state = 539 self._errHandler.sync(self) _la = self._input.LA(1) diff --git a/pymongosql/sql/partiql/PartiQLParserListener.py b/pymongosql/sql/partiql/PartiQLParserListener.py index 8ea0a39..2933b85 100644 --- a/pymongosql/sql/partiql/PartiQLParserListener.py +++ b/pymongosql/sql/partiql/PartiQLParserListener.py @@ -1,4 +1,4 @@ -# Generated from PartiQLParser.g4 by ANTLR 4.13.2 +# Generated from PartiQLParser.g4 by ANTLR 4.13.0 from antlr4 import * if "." in __name__: from .PartiQLParser import PartiQLParser diff --git a/pymongosql/sql/partiql/PartiQLParserVisitor.py b/pymongosql/sql/partiql/PartiQLParserVisitor.py index 6ed03a4..772d3ea 100644 --- a/pymongosql/sql/partiql/PartiQLParserVisitor.py +++ b/pymongosql/sql/partiql/PartiQLParserVisitor.py @@ -1,4 +1,4 @@ -# Generated from PartiQLParser.g4 by ANTLR 4.13.2 +# Generated from PartiQLParser.g4 by ANTLR 4.13.0 from antlr4 import * if "." in __name__: from .PartiQLParser import PartiQLParser diff --git a/tests/conftest.py b/tests/conftest.py index 1008428..dc50af4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -77,3 +77,79 @@ def superset_conn(): def make_connection(): """Provide the helper make_conn function to tests that need to create connections with custom args.""" return make_conn + + +# SQLAlchemy version compatibility +try: + import sqlalchemy + from sqlalchemy import create_engine + from sqlalchemy.orm import sessionmaker + + SQLALCHEMY_VERSION = tuple(map(int, sqlalchemy.__version__.split(".")[:2])) + SQLALCHEMY_2X = SQLALCHEMY_VERSION >= (2, 0) + HAS_SQLALCHEMY = True + + # Handle declarative base differences + if SQLALCHEMY_2X: + try: + from sqlalchemy.orm import DeclarativeBase, Session + + class Base(DeclarativeBase): + pass + + except ImportError: + from sqlalchemy.ext.declarative import declarative_base + + Base = declarative_base() + from sqlalchemy.orm import Session + else: + from sqlalchemy.ext.declarative import declarative_base + from sqlalchemy.orm import Session + + Base = declarative_base() + +except ImportError: + SQLALCHEMY_VERSION = None + SQLALCHEMY_2X = False + HAS_SQLALCHEMY = False + Base = None + Session = None + +# SQLAlchemy fixtures for dialect testing +if HAS_SQLALCHEMY: + + @pytest.fixture + def sqlalchemy_engine(): + """Provide a SQLAlchemy engine connected to MongoDB. The URI is taken from environment variables + (PYMONGOSQL_TEST_URI or MONGODB_URI) or falls back to a sensible local default. + """ + uri = os.environ.get("PYMONGOSQL_TEST_URI") or os.environ.get("MONGODB_URI") or TEST_URI + db = os.environ.get("PYMONGOSQL_TEST_DB") or TEST_DB + + def _ensure_uri_has_db(uri_value: str, database: str) -> str: + if not database: + return uri_value + idx = uri_value.find("://") + if idx == -1: + return uri_value + rest = uri_value[idx + 3 :] + if "/" in rest: + after = rest.split("/", 1)[1] + if after == "" or after.startswith("?"): + return uri_value.rstrip("/") + "/" + database + return uri_value + return uri_value.rstrip("/") + "/" + database + + if uri: + uri_to_use = _ensure_uri_has_db(uri, db) + else: + uri_to_use = "mongodb://testuser:testpass@localhost:27017/test_db" + + engine = create_engine(uri_to_use) + yield engine + engine.dispose() + + @pytest.fixture + def session_maker(sqlalchemy_engine): + """Provide a SQLAlchemy session maker.""" + return sessionmaker(bind=sqlalchemy_engine) diff --git a/tests/test_cursor_insert.py b/tests/test_cursor_insert.py index 13bc2eb..145fcc6 100644 --- a/tests/test_cursor_insert.py +++ b/tests/test_cursor_insert.py @@ -150,6 +150,22 @@ def test_insert_multiple_documents_with_parameters(self, conn): assert "Iris" in doc_by_name assert doc_by_name["Iris"]["age"] == 29 + def test_insert_with_column_list_and_values(self, conn): + """Test INSERT with explicit column list and VALUES clause.""" + sql = f"INSERT INTO {self.TEST_COLLECTION} (name, age, city) VALUES ('Kevin', 40, 'Kansas City')" + cursor = conn.cursor() + result = cursor.execute(sql) + + assert result == cursor # execute returns self + + # Verify the document was inserted with correct fields + db = conn.database + docs = list(db[self.TEST_COLLECTION].find()) + assert len(docs) == 1 + assert docs[0]["name"] == "Kevin" + assert docs[0]["age"] == 40 + assert docs[0]["city"] == "Kansas City" + def test_insert_insufficient_parameters_raises_error(self, conn): """Test that insufficient parameters raises ProgrammingError.""" sql = f"INSERT INTO {self.TEST_COLLECTION} {{'name': '?', 'age': '?'}}" diff --git a/tests/test_sql_parser_insert.py b/tests/test_sql_parser_insert.py index 767e1cd..ff09fff 100644 --- a/tests/test_sql_parser_insert.py +++ b/tests/test_sql_parser_insert.py @@ -78,54 +78,6 @@ def test_insert_single_tuple(self): } ] - # Not supported in PartiQL Grammar yet - # - # def test_insert_values_single_row(self): - # sql = ( - # "INSERT INTO Films (code, title, did, date_prod, kind) " - # "VALUES ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy')" - # ) - # plan = SQLParser("".join(sql)).get_execution_plan() - - # assert isinstance(plan, InsertExecutionPlan) - # assert plan.collection == "Films" - # assert plan.insert_documents == [ - # { - # "code": "B6717", - # "title": "Tampopo", - # "did": 110, - # "date_prod": "1985-02-10", - # "kind": "Comedy", - # } - # ] - - # def test_insert_values_multiple_rows(self): - # sql = ( - # "INSERT INTO Films (code, title, did, date_prod, kind) " - # "VALUES ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy')," - # " ('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy')" - # ) - # plan = SQLParser("".join(sql)).get_execution_plan() - - # assert isinstance(plan, InsertExecutionPlan) - # assert plan.collection == "Films" - # assert plan.insert_documents == [ - # { - # "code": "B6717", - # "title": "Tampopo", - # "did": 110, - # "date_prod": "1985-02-10", - # "kind": "Comedy", - # }, - # { - # "code": "HG120", - # "title": "The Dinner Game", - # "did": 140, - # "date_prod": None, - # "kind": "Comedy", - # }, - # ] - def test_insert_invalid_expression_raises(self): sql = "INSERT INTO users 123" with pytest.raises(SqlSyntaxError): diff --git a/tests/test_sql_parser_insert_values.py b/tests/test_sql_parser_insert_values.py new file mode 100644 index 0000000..1b18d7d --- /dev/null +++ b/tests/test_sql_parser_insert_values.py @@ -0,0 +1,146 @@ +# -*- coding: utf-8 -*- +from pymongosql.sql.insert_builder import InsertExecutionPlan +from pymongosql.sql.parser import SQLParser + + +class TestSQLParserInsertValues: + """Tests for INSERT parsing with VALUES clause.""" + + def test_insert_single_row_implicit_columns(self): + """Test INSERT with single row without column list.""" + sql = "INSERT INTO users VALUES (1, 'Alice', 30)" + plan = SQLParser(sql).get_execution_plan() + + assert isinstance(plan, InsertExecutionPlan) + assert plan.collection == "users" + assert len(plan.insert_documents) == 1 + assert plan.insert_documents == [{"col0": 1, "col1": "Alice", "col2": 30}] + + def test_insert_multiple_rows_implicit_columns(self): + """Test INSERT with multiple rows without column list.""" + sql = "INSERT INTO users VALUES (1, 'Alice', 30), (2, 'Bob', 25)" + plan = SQLParser(sql).get_execution_plan() + + assert plan.collection == "users" + assert len(plan.insert_documents) == 2 + assert plan.insert_documents == [ + {"col0": 1, "col1": "Alice", "col2": 30}, + {"col0": 2, "col1": "Bob", "col2": 25}, + ] + + def test_insert_single_row_explicit_columns(self): + """Test INSERT with single row and explicit column list.""" + sql = "INSERT INTO users (id, name, age) VALUES (1, 'Alice', 30)" + plan = SQLParser(sql).get_execution_plan() + + assert plan.collection == "users" + assert len(plan.insert_documents) == 1 + assert plan.insert_documents == [{"id": 1, "name": "Alice", "age": 30}] + + def test_insert_multiple_rows_explicit_columns(self): + """Test INSERT with multiple rows and explicit column list.""" + sql = "INSERT INTO users (id, name, age) VALUES (1, 'Alice', 30), (2, 'Bob', 25)" + plan = SQLParser(sql).get_execution_plan() + + assert plan.collection == "users" + assert len(plan.insert_documents) == 2 + assert plan.insert_documents == [{"id": 1, "name": "Alice", "age": 30}, {"id": 2, "name": "Bob", "age": 25}] + + def test_insert_with_null_value(self): + """Test INSERT with NULL values.""" + sql = "INSERT INTO users (id, name, email) VALUES (1, 'Alice', NULL)" + plan = SQLParser(sql).get_execution_plan() + + assert plan.collection == "users" + assert plan.insert_documents == [{"id": 1, "name": "Alice", "email": None}] + + def test_insert_with_boolean_values(self): + """Test INSERT with boolean values.""" + sql = "INSERT INTO flags (id, is_active, is_deleted) VALUES (1, TRUE, FALSE)" + plan = SQLParser(sql).get_execution_plan() + + assert plan.collection == "flags" + assert plan.insert_documents == [{"id": 1, "is_active": True, "is_deleted": False}] + + def test_insert_with_positional_parameters(self): + """Test INSERT with positional parameters (?).""" + sql = "INSERT INTO users (id, name) VALUES (?, ?)" + plan = SQLParser(sql).get_execution_plan() + + assert plan.collection == "users" + assert plan.insert_documents == [{"id": "?", "name": "?"}] + + def test_insert_with_numeric_values(self): + """Test INSERT with integer and decimal values.""" + sql = "INSERT INTO products (id, name, price, quantity) VALUES (1, 'Widget', 19.99, 100)" + plan = SQLParser(sql).get_execution_plan() + + assert plan.collection == "products" + assert plan.insert_documents == [{"id": 1, "name": "Widget", "price": 19.99, "quantity": 100}] + + def test_insert_empty_string(self): + """Test INSERT with empty string.""" + sql = "INSERT INTO users (id, name) VALUES (1, '')" + plan = SQLParser(sql).get_execution_plan() + + assert plan.collection == "users" + assert plan.insert_documents == [{"id": 1, "name": ""}] + + def test_insert_multiple_rows_mixed_types(self): + """Test INSERT with multiple rows containing mixed types.""" + sql = "INSERT INTO data (id, data_value) VALUES (1, 'text'), (2, 42), (3, NULL)" + plan = SQLParser(sql).get_execution_plan() + + assert plan.collection == "data" + assert len(plan.insert_documents) == 3 + assert plan.insert_documents == [ + {"id": 1, "data_value": "text"}, + {"id": 2, "data_value": 42}, + {"id": 3, "data_value": None}, + ] + + def test_insert_values_single_row(self): + sql = ( + "INSERT INTO Films (code, title, did, date_prod, kind) " + "VALUES ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy')" + ) + plan = SQLParser("".join(sql)).get_execution_plan() + + assert isinstance(plan, InsertExecutionPlan) + assert plan.collection == "Films" + assert plan.insert_documents == [ + { + "code": "B6717", + "title": "Tampopo", + "did": 110, + "date_prod": "1985-02-10", + "kind": "Comedy", + } + ] + + def test_insert_values_multiple_rows(self): + sql = ( + "INSERT INTO Films (code, title, did, date_prod, kind) " + "VALUES ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy')," + " ('HG120', 'The Dinner Game', 140, NULL, 'Comedy')" + ) + plan = SQLParser("".join(sql)).get_execution_plan() + + assert isinstance(plan, InsertExecutionPlan) + assert plan.collection == "Films" + assert plan.insert_documents == [ + { + "code": "B6717", + "title": "Tampopo", + "did": 110, + "date_prod": "1985-02-10", + "kind": "Comedy", + }, + { + "code": "HG120", + "title": "The Dinner Game", + "did": 140, + "date_prod": None, + "kind": "Comedy", + }, + ] diff --git a/tests/test_sqlalchemy_dml.py b/tests/test_sqlalchemy_dml.py new file mode 100644 index 0000000..70ae7f4 --- /dev/null +++ b/tests/test_sqlalchemy_dml.py @@ -0,0 +1,678 @@ +#!/usr/bin/env python3 +import pytest + +from tests.conftest import HAS_SQLALCHEMY, Base + +try: + from sqlalchemy import Boolean, Column, Float, Integer, String, text +except ImportError: + pass + +# Skip all tests if SQLAlchemy is not available +pytestmark = pytest.mark.skipif(not HAS_SQLALCHEMY, reason="SQLAlchemy not available") + + +# ORM Models for testing +if HAS_SQLALCHEMY: + + class TestUser(Base): + """Test user model for DML operations.""" + + __tablename__ = "test_users_orm" + + id = Column(Integer, primary_key=True) + name = Column(String(100)) + email = Column(String(100)) + age = Column(Integer) + is_active = Column(Boolean, default=True) + + class TestProduct(Base): + """Test product model for DML operations.""" + + __tablename__ = "test_products_orm" + + id = Column(Integer, primary_key=True) + name = Column(String(100)) + price = Column(Float) + quantity = Column(Integer) + in_stock = Column(Boolean, default=True) + + +class TestSQLAlchemyDML: + """Test SQLAlchemy dialect with DML operations (INSERT, UPDATE, DELETE).""" + + def test_insert_single_row_explicit_columns(self, sqlalchemy_engine, conn): + """Test INSERT with single row and explicit columns via SQLAlchemy.""" + with sqlalchemy_engine.connect() as connection: + # Clean up test data first + try: + connection.execute(text("DELETE FROM test_insert_values")) + connection.commit() + except Exception: + pass + + # Insert single row with VALUES clause + sql = "INSERT INTO test_insert_values (id, name, age) VALUES (1, 'Alice', 30)" + connection.execute(text(sql)) + connection.commit() + + # Verify the insert + result = connection.execute(text("SELECT id, name, age FROM test_insert_values WHERE id = 1")) + row = result.fetchone() + + assert row is not None + if hasattr(row, "_mapping"): + assert row._mapping.get("id") == 1 + assert row._mapping.get("name") == "Alice" + assert row._mapping.get("age") == 30 + else: + assert row[0] == 1 + assert row[1] == "Alice" + assert row[2] == 30 + + # Clean up + connection.execute(text("DELETE FROM test_insert_values")) + connection.commit() + + def test_insert_multiple_rows_explicit_columns(self, sqlalchemy_engine, conn): + """Test INSERT with multiple rows and explicit columns via SQLAlchemy.""" + with sqlalchemy_engine.connect() as connection: + # Clean up test data first + try: + connection.execute(text("DELETE FROM test_insert_values")) + connection.commit() + except Exception: + pass + + # Insert multiple rows with VALUES clause + sql = "INSERT INTO test_insert_values (id, name, age) VALUES (1, 'Alice', 30), (2, 'Bob', 25)" + connection.execute(text(sql)) + connection.commit() + + # Verify the inserts + result = connection.execute(text("SELECT id, name, age FROM test_insert_values ORDER BY id")) + rows = result.fetchall() + + assert len(rows) == 2 + + # Check first row + if hasattr(rows[0], "_mapping"): + assert rows[0]._mapping.get("id") == 1 + assert rows[0]._mapping.get("name") == "Alice" + assert rows[0]._mapping.get("age") == 30 + assert rows[1]._mapping.get("id") == 2 + assert rows[1]._mapping.get("name") == "Bob" + assert rows[1]._mapping.get("age") == 25 + else: + assert rows[0][0] == 1 + assert rows[0][1] == "Alice" + assert rows[0][2] == 30 + assert rows[1][0] == 2 + assert rows[1][1] == "Bob" + assert rows[1][2] == 25 + + # Clean up + connection.execute(text("DELETE FROM test_insert_values")) + connection.commit() + + def test_insert_single_row_implicit_columns(self, sqlalchemy_engine, conn): + """Test INSERT with single row without column list via SQLAlchemy.""" + with sqlalchemy_engine.connect() as connection: + # Clean up test data first + try: + connection.execute(text("DELETE FROM test_insert_implicit")) + connection.commit() + except Exception: + pass + + # Insert single row with VALUES clause (implicit columns) + sql = "INSERT INTO test_insert_implicit VALUES (1, 'Alice', 30)" + connection.execute(text(sql)) + connection.commit() + + # Verify the insert (auto-named columns: col0, col1, col2) + result = connection.execute(text("SELECT col0, col1, col2 FROM test_insert_implicit WHERE col0 = 1")) + row = result.fetchone() + + assert row is not None + if hasattr(row, "_mapping"): + assert row._mapping.get("col0") == 1 + assert row._mapping.get("col1") == "Alice" + assert row._mapping.get("col2") == 30 + else: + assert row[0] == 1 + assert row[1] == "Alice" + assert row[2] == 30 + + # Clean up + connection.execute(text("DELETE FROM test_insert_implicit")) + connection.commit() + + def test_insert_with_null_values(self, sqlalchemy_engine, conn): + """Test INSERT with NULL values via SQLAlchemy.""" + with sqlalchemy_engine.connect() as connection: + # Clean up test data first + try: + connection.execute(text("DELETE FROM test_insert_null")) + connection.commit() + except Exception: + pass + + # Insert with NULL value + sql = "INSERT INTO test_insert_null (id, name, email) VALUES (1, 'Alice', NULL)" + connection.execute(text(sql)) + connection.commit() + + # Verify the insert + result = connection.execute(text("SELECT id, name, email FROM test_insert_null WHERE id = 1")) + row = result.fetchone() + + assert row is not None + if hasattr(row, "_mapping"): + assert row._mapping.get("id") == 1 + assert row._mapping.get("name") == "Alice" + assert row._mapping.get("email") is None + else: + assert row[0] == 1 + assert row[1] == "Alice" + assert row[2] is None + + # Clean up + connection.execute(text("DELETE FROM test_insert_null")) + connection.commit() + + def test_insert_with_boolean_values(self, sqlalchemy_engine, conn): + """Test INSERT with boolean values via SQLAlchemy.""" + with sqlalchemy_engine.connect() as connection: + # Clean up test data first + try: + connection.execute(text("DELETE FROM test_insert_bool")) + connection.commit() + except Exception: + pass + + # Insert with boolean values + sql = "INSERT INTO test_insert_bool (id, is_active, is_deleted) VALUES (1, TRUE, FALSE)" + connection.execute(text(sql)) + connection.commit() + + # Verify the insert + result = connection.execute(text("SELECT id, is_active, is_deleted FROM test_insert_bool WHERE id = 1")) + row = result.fetchone() + + assert row is not None + if hasattr(row, "_mapping"): + assert row._mapping.get("id") == 1 + assert row._mapping.get("is_active") is True + assert row._mapping.get("is_deleted") is False + else: + assert row[0] == 1 + assert row[1] is True + assert row[2] is False + + # Clean up + connection.execute(text("DELETE FROM test_insert_bool")) + connection.commit() + + def test_orm_table_insert_single_row(self, session_maker, conn): + """Test INSERT VALUES with ORM table using raw SQL.""" + session = session_maker() + try: + # Clean up first + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + + # Insert using VALUES clause with ORM table + sql = """ + INSERT INTO test_users_orm (id, name, email, age, is_active) + VALUES (1, 'Alice', 'alice@example.com', 30, TRUE) + """ + session.execute(text(sql)) + session.commit() + + # Verify the insert + result = session.execute(text("SELECT id, name, email, age, is_active FROM test_users_orm WHERE id = 1")) + row = result.fetchone() + + assert row is not None + if hasattr(row, "_mapping"): + assert row._mapping.get("id") == 1 + assert row._mapping.get("name") == "Alice" + assert row._mapping.get("email") == "alice@example.com" + assert row._mapping.get("age") == 30 + assert row._mapping.get("is_active") is True + else: + assert row[0] == 1 + assert row[1] == "Alice" + assert row[2] == "alice@example.com" + assert row[3] == 30 + assert row[4] is True + + finally: + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + session.close() + + def test_orm_table_insert_multiple_rows(self, session_maker, conn): + """Test INSERT VALUES with ORM table using raw SQL for multiple rows.""" + session = session_maker() + try: + # Clean up first + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + + # Insert multiple rows using VALUES clause + sql = """ + INSERT INTO test_users_orm (id, name, email, age, is_active) + VALUES + (1, 'Alice', 'alice@example.com', 30, TRUE), + (2, 'Bob', 'bob@example.com', 25, TRUE), + (3, 'Charlie', 'charlie@example.com', 35, FALSE) + """ + session.execute(text(sql)) + session.commit() + + # Verify the inserts + result = session.execute(text("SELECT id, name, age, is_active FROM test_users_orm ORDER BY id")) + rows = result.fetchall() + + assert len(rows) == 3 + if hasattr(rows[0], "_mapping"): + assert rows[0]._mapping.get("id") == 1 + assert rows[0]._mapping.get("name") == "Alice" + assert rows[0]._mapping.get("is_active") is True + assert rows[1]._mapping.get("id") == 2 + assert rows[1]._mapping.get("name") == "Bob" + assert rows[2]._mapping.get("id") == 3 + assert rows[2]._mapping.get("name") == "Charlie" + assert rows[2]._mapping.get("is_active") is False + else: + assert rows[0][0] == 1 + assert rows[0][1] == "Alice" + assert rows[1][0] == 2 + assert rows[1][1] == "Bob" + assert rows[2][0] == 3 + assert rows[2][1] == "Charlie" + + finally: + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + session.close() + + def test_orm_table_update_single_row(self, session_maker, conn): + """Test UPDATE using ORM table with raw SQL.""" + session = session_maker() + try: + # Clean up and insert test data + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + + session.execute( + text( + "INSERT INTO test_users_orm (id, name, email, age, is_active) " + "VALUES (1, 'Alice', 'alice@example.com', 30, TRUE)" + ) + ) + session.commit() + + # Update the user + session.execute( + text("UPDATE test_users_orm SET age = 31, email = 'alice.updated@example.com' WHERE id = 1") + ) + session.commit() + + # Verify the update + result = session.execute(text("SELECT id, name, email, age FROM test_users_orm WHERE id = 1")) + row = result.fetchone() + + assert row is not None + if hasattr(row, "_mapping"): + assert row._mapping.get("id") == 1 + assert row._mapping.get("name") == "Alice" + assert row._mapping.get("email") == "alice.updated@example.com" + assert row._mapping.get("age") == 31 + else: + assert row[0] == 1 + assert row[1] == "Alice" + assert row[2] == "alice.updated@example.com" + assert row[3] == 31 + + finally: + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + session.close() + + def test_orm_table_update_multiple_rows(self, session_maker, conn): + """Test UPDATE using ORM table with multiple rows.""" + session = session_maker() + try: + # Clean up and insert test data + session.execute(text("DELETE FROM test_products_orm")) + session.commit() + + session.execute( + text( + "INSERT INTO test_products_orm (id, name, price, quantity, in_stock) VALUES " + "(1, 'Widget', 19.99, 100, TRUE), " + "(2, 'Gadget', 29.99, 50, TRUE), " + "(3, 'Tool', 9.99, 0, FALSE)" + ) + ) + session.commit() + + # Update multiple products - set quantity to 200 for in-stock items + session.execute(text("UPDATE test_products_orm SET quantity = 200 WHERE in_stock = TRUE")) + session.commit() + + # Verify the updates + result = session.execute(text("SELECT id, name, quantity, in_stock FROM test_products_orm ORDER BY id")) + rows = result.fetchall() + + assert len(rows) == 3 + if hasattr(rows[0], "_mapping"): + # First two should have updated quantity + assert rows[0]._mapping.get("quantity") == 200 + assert rows[1]._mapping.get("quantity") == 200 + # Third should remain unchanged + assert rows[2]._mapping.get("quantity") == 0 + else: + assert rows[0][2] == 200 + assert rows[1][2] == 200 + assert rows[2][2] == 0 + + finally: + session.execute(text("DELETE FROM test_products_orm")) + session.commit() + session.close() + + def test_orm_table_delete_single_row(self, session_maker, conn): + """Test DELETE using ORM table with raw SQL.""" + session = session_maker() + try: + # Clean up and insert test data + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + + session.execute( + text( + "INSERT INTO test_users_orm (id, name, email, age) VALUES " + "(1, 'Alice', 'alice@example.com', 30), " + "(2, 'Bob', 'bob@example.com', 25)" + ) + ) + session.commit() + + # Delete one user + session.execute(text("DELETE FROM test_users_orm WHERE id = 1")) + session.commit() + + # Verify the delete + result = session.execute(text("SELECT id, name FROM test_users_orm ORDER BY id")) + rows = result.fetchall() + + assert len(rows) == 1 + if hasattr(rows[0], "_mapping"): + assert rows[0]._mapping.get("id") == 2 + assert rows[0]._mapping.get("name") == "Bob" + else: + assert rows[0][0] == 2 + assert rows[0][1] == "Bob" + + finally: + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + session.close() + + def test_orm_table_delete_with_condition(self, session_maker, conn): + """Test DELETE using ORM table with WHERE condition.""" + session = session_maker() + try: + # Clean up and insert test data + session.execute(text("DELETE FROM test_products_orm")) + session.commit() + + session.execute( + text( + "INSERT INTO test_products_orm (id, name, price, quantity, in_stock) VALUES " + "(1, 'Widget', 19.99, 100, TRUE), " + "(2, 'Gadget', 29.99, 0, FALSE), " + "(3, 'Tool', 9.99, 5, TRUE)" + ) + ) + session.commit() + + # Delete all out-of-stock products + session.execute(text("DELETE FROM test_products_orm WHERE in_stock = FALSE")) + session.commit() + + # Verify the delete + result = session.execute(text("SELECT id, name, in_stock FROM test_products_orm ORDER BY id")) + rows = result.fetchall() + + assert len(rows) == 2 + if hasattr(rows[0], "_mapping"): + assert rows[0]._mapping.get("id") == 1 + assert rows[0]._mapping.get("in_stock") is True + assert rows[1]._mapping.get("id") == 3 + assert rows[1]._mapping.get("in_stock") is True + else: + assert rows[0][0] == 1 + assert rows[0][2] is True + assert rows[1][0] == 3 + assert rows[1][2] is True + + finally: + session.execute(text("DELETE FROM test_products_orm")) + session.commit() + session.close() + + def test_orm_insert_single_object(self, session_maker, conn): + """Test pure ORM INSERT using session.add() with a single object. + + Note: Uses text() for verification due to ORM query limitations with parameterized queries. + """ + session = session_maker() + try: + # Clean up first + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + + # Create and insert a user using pure ORM + user = TestUser() + user.id = 100 + user.name = "John Doe" + user.email = "john@example.com" + user.age = 28 + user.is_active = True + + session.add(user) + session.commit() + + # Verify the insert using raw SQL (ORM queries have parameter issues) + result = session.execute(text("SELECT id, name, email, age, is_active FROM test_users_orm WHERE id = 100")) + row = result.fetchone() + + assert row is not None + if hasattr(row, "_mapping"): + assert row._mapping.get("id") == 100 + assert row._mapping.get("name") == "John Doe" + assert row._mapping.get("email") == "john@example.com" + assert row._mapping.get("age") == 28 + assert row._mapping.get("is_active") is True + else: + assert row[0] == 100 + assert row[1] == "John Doe" + assert row[2] == "john@example.com" + assert row[3] == 28 + assert row[4] is True + + finally: + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + session.close() + + def test_orm_insert_multiple_objects_individually(self, session_maker, conn): + """Test pure ORM INSERT with multiple objects added individually. + + Note: Uses individual add() calls instead of add_all() due to executemany limitations. + """ + session = session_maker() + try: + # Clean up first + session.execute(text("DELETE FROM test_products_orm")) + session.commit() + + # Create and insert products using pure ORM - add individually + product1 = TestProduct() + product1.id = 200 + product1.name = "Laptop" + product1.price = 999.99 + product1.quantity = 10 + product1.in_stock = True + session.add(product1) + session.commit() + + product2 = TestProduct() + product2.id = 201 + product2.name = "Mouse" + product2.price = 25.50 + product2.quantity = 50 + product2.in_stock = True + session.add(product2) + session.commit() + + product3 = TestProduct() + product3.id = 202 + product3.name = "Keyboard" + product3.price = 75.00 + product3.quantity = 0 + product3.in_stock = False + session.add(product3) + session.commit() + + # Verify the inserts + result = session.execute( + text("SELECT id, name, price, quantity, in_stock FROM test_products_orm ORDER BY id") + ) + rows = result.fetchall() + + assert len(rows) == 3 + if hasattr(rows[0], "_mapping"): + assert rows[0]._mapping.get("id") == 200 + assert rows[0]._mapping.get("name") == "Laptop" + assert rows[0]._mapping.get("price") == 999.99 + assert rows[1]._mapping.get("id") == 201 + assert rows[1]._mapping.get("name") == "Mouse" + assert rows[2]._mapping.get("id") == 202 + assert rows[2]._mapping.get("in_stock") is False + else: + assert rows[0][0] == 200 + assert rows[0][1] == "Laptop" + assert rows[1][0] == 201 + assert rows[2][0] == 202 + + finally: + session.execute(text("DELETE FROM test_products_orm")) + session.commit() + session.close() + + def test_orm_update_via_raw_sql(self, session_maker, conn): + """Test ORM model UPDATE using raw SQL. + + Note: Pure ORM update (query/modify/commit) not currently supported due to + parameterized query limitations in the dialect. + """ + session = session_maker() + try: + # Clean up and insert test data + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + + # Create and insert initial user using ORM + user = TestUser() + user.id = 300 + user.name = "Jane Smith" + user.email = "jane@example.com" + user.age = 25 + user.is_active = True + session.add(user) + session.commit() + + # Update using raw SQL (ORM query-based updates have parameterization issues) + session.execute( + text( + "UPDATE test_users_orm SET age = 26, email = 'jane.updated@example.com', is_active = FALSE WHERE id = 300" + ) + ) + session.commit() + + # Verify the update + result = session.execute(text("SELECT id, name, email, age, is_active FROM test_users_orm WHERE id = 300")) + row = result.fetchone() + + assert row is not None + if hasattr(row, "_mapping"): + assert row._mapping.get("age") == 26 + assert row._mapping.get("email") == "jane.updated@example.com" + assert row._mapping.get("is_active") is False + else: + assert row[3] == 26 + assert row[2] == "jane.updated@example.com" + assert row[4] is False + + finally: + session.execute(text("DELETE FROM test_users_orm")) + session.commit() + session.close() + + def test_orm_delete_via_raw_sql(self, session_maker, conn): + """Test ORM model DELETE using raw SQL. + + Note: Pure ORM delete (query/delete/commit) not currently supported due to + parameterized query limitations in the dialect. + """ + session = session_maker() + try: + # Clean up and insert test data + session.execute(text("DELETE FROM test_products_orm")) + session.commit() + + # Create and insert products using ORM + product1 = TestProduct() + product1.id = 400 + product1.name = "Monitor" + product1.price = 299.99 + product1.quantity = 15 + product1.in_stock = True + session.add(product1) + session.commit() + + product2 = TestProduct() + product2.id = 401 + product2.name = "Speaker" + product2.price = 49.99 + product2.quantity = 30 + product2.in_stock = True + session.add(product2) + session.commit() + + # Delete using raw SQL (ORM query-based deletes have parameterization issues) + session.execute(text("DELETE FROM test_products_orm WHERE id = 400")) + session.commit() + + # Verify the delete + result = session.execute(text("SELECT id, name FROM test_products_orm ORDER BY id")) + rows = result.fetchall() + + assert len(rows) == 1 + if hasattr(rows[0], "_mapping"): + assert rows[0]._mapping.get("id") == 401 + assert rows[0]._mapping.get("name") == "Speaker" + else: + assert rows[0][0] == 401 + assert rows[0][1] == "Speaker" + + finally: + session.execute(text("DELETE FROM test_products_orm")) + session.commit() + session.close() diff --git a/tests/test_sqlalchemy_integration.py b/tests/test_sqlalchemy_query.py similarity index 79% rename from tests/test_sqlalchemy_integration.py rename to tests/test_sqlalchemy_query.py index bc8d05b..091ac89 100644 --- a/tests/test_sqlalchemy_integration.py +++ b/tests/test_sqlalchemy_query.py @@ -1,45 +1,12 @@ #!/usr/bin/env python3 -import os - import pytest -from tests.conftest import TEST_DB, TEST_URI +from tests.conftest import HAS_SQLALCHEMY, Base -# SQLAlchemy version compatibility try: - import sqlalchemy - from sqlalchemy import JSON, Boolean, Column, Float, Integer, String, create_engine - from sqlalchemy.orm import sessionmaker - - SQLALCHEMY_VERSION = tuple(map(int, sqlalchemy.__version__.split(".")[:2])) - SQLALCHEMY_2X = SQLALCHEMY_VERSION >= (2, 0) - HAS_SQLALCHEMY = True - - # Handle declarative base differences - if SQLALCHEMY_2X: - try: - from sqlalchemy.orm import DeclarativeBase, Session - - class Base(DeclarativeBase): - pass - - except ImportError: - from sqlalchemy.ext.declarative import declarative_base - - Base = declarative_base() - from sqlalchemy.orm import Session - else: - from sqlalchemy.ext.declarative import declarative_base - from sqlalchemy.orm import Session - - Base = declarative_base() - + from sqlalchemy import JSON, Boolean, Column, Float, Integer, String, text except ImportError: - SQLALCHEMY_VERSION = None - SQLALCHEMY_2X = False - HAS_SQLALCHEMY = False - Base = None - Session = None + pass # Skip all tests if SQLAlchemy is not available pytestmark = pytest.mark.skipif(not HAS_SQLALCHEMY, reason="SQLAlchemy not available") @@ -98,46 +65,8 @@ def __repr__(self): return f"" -# Pytest fixtures -@pytest.fixture -def sqlalchemy_engine(): - """Provide a SQLAlchemy engine connected to MongoDB. The URI is taken from environment variables - (PYMONGOSQL_TEST_URI or MONGODB_URI) or falls back to a sensible local default. - """ - uri = os.environ.get("PYMONGOSQL_TEST_URI") or os.environ.get("MONGODB_URI") or TEST_URI - db = os.environ.get("PYMONGOSQL_TEST_DB") or TEST_DB - - def _ensure_uri_has_db(uri_value: str, database: str) -> str: - if not database: - return uri_value - idx = uri_value.find("://") - if idx == -1: - return uri_value - rest = uri_value[idx + 3 :] - if "/" in rest: - after = rest.split("/", 1)[1] - if after == "" or after.startswith("?"): - return uri_value.rstrip("/") + "/" + database - return uri_value - return uri_value.rstrip("/") + "/" + database - - if uri: - uri_to_use = _ensure_uri_has_db(uri, db) - else: - uri_to_use = "mongodb://testuser:testpass@localhost:27017/test_db" - - engine = create_engine(uri_to_use) - yield engine - - -@pytest.fixture -def session_maker(sqlalchemy_engine): - """Provide a SQLAlchemy session maker.""" - return sessionmaker(bind=sqlalchemy_engine) - - -class TestSQLAlchemyIntegration: - """Test class for SQLAlchemy dialect integration with real MongoDB data.""" +class TestSQLAlchemyQuery: + """Test class for SQLAlchemy dialect query operations with real MongoDB data.""" def test_engine_creation(self, sqlalchemy_engine): """Test that SQLAlchemy engine works with real MongoDB.""" @@ -152,9 +81,7 @@ def test_read_users_data(self, sqlalchemy_engine): """Test reading users data and creating User objects.""" with sqlalchemy_engine.connect() as connection: # Query real users data - result = connection.execute( - sqlalchemy.text("SELECT _id, name, email, age, city, active, balance FROM users LIMIT 5") - ) + result = connection.execute(text("SELECT _id, name, email, age, city, active, balance FROM users LIMIT 5")) rows = result.fetchall() assert len(rows) > 0, "Should have user data in test database" @@ -204,7 +131,7 @@ def test_read_products_data(self, sqlalchemy_engine): with sqlalchemy_engine.connect() as connection: # Query real products data result = connection.execute( - sqlalchemy.text("SELECT _id, name, price, category, in_stock, quantity FROM products LIMIT 5") + text("SELECT _id, name, price, category, in_stock, quantity FROM products LIMIT 5") ) rows = result.fetchall() @@ -255,7 +182,7 @@ def test_session_based_queries(self, session_maker): try: # Test session-based query execution - result = session.execute(sqlalchemy.text("SELECT _id, name, email FROM users LIMIT 3")) + result = session.execute(text("SELECT _id, name, email FROM users LIMIT 3")) rows = result.fetchall() assert len(rows) > 0, "Should have user data available" @@ -295,7 +222,7 @@ def test_complex_queries_with_filtering(self, sqlalchemy_engine): """Test more complex SQL queries with WHERE conditions.""" with sqlalchemy_engine.connect() as connection: # Test filtering queries - result = connection.execute(sqlalchemy.text("SELECT _id, name, age FROM users WHERE age > 25 LIMIT 5")) + result = connection.execute(text("SELECT _id, name, age FROM users WHERE age > 25 LIMIT 5")) rows = result.fetchall() if len(rows) > 0: # Only test if we have data @@ -336,8 +263,8 @@ def test_multiple_table_queries(self, sqlalchemy_engine): """Test querying multiple collections (tables).""" with sqlalchemy_engine.connect() as connection: # Test querying different collections - users_result = connection.execute(sqlalchemy.text("SELECT _id, name FROM users LIMIT 2")) - products_result = connection.execute(sqlalchemy.text("SELECT _id, name, price FROM products LIMIT 2")) + users_result = connection.execute(text("SELECT _id, name FROM users LIMIT 2")) + products_result = connection.execute(text("SELECT _id, name, price FROM products LIMIT 2")) users_rows = users_result.fetchall() products_rows = products_result.fetchall() From 3d6ef7e301ae0873051350cf36374d1d81417268 Mon Sep 17 00:00:00 2001 From: Peng Ren Date: Tue, 30 Dec 2025 17:06:00 -0500 Subject: [PATCH 4/5] Fixed test case issue --- tests/conftest.py | 3 +++ tests/test_sqlalchemy_dml.py | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index dc50af4..ce220d5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,6 +5,9 @@ from pymongosql.connection import Connection +# Silence SQLAlchemy 1.4 deprecation warnings in tests +os.environ.setdefault("SQLALCHEMY_SILENCE_UBER_WARNING", "1") + # Centralized test configuration sourced from environment to allow running tests # against remote MongoDB (e.g. Atlas) or local test instance. TEST_URI = os.environ.get("PYMONGOSQL_TEST_URI") or os.environ.get("MONGODB_URI") diff --git a/tests/test_sqlalchemy_dml.py b/tests/test_sqlalchemy_dml.py index 70ae7f4..b72bdc9 100644 --- a/tests/test_sqlalchemy_dml.py +++ b/tests/test_sqlalchemy_dml.py @@ -15,8 +15,8 @@ # ORM Models for testing if HAS_SQLALCHEMY: - class TestUser(Base): - """Test user model for DML operations.""" + class User(Base): + """User model for DML operations testing.""" __tablename__ = "test_users_orm" @@ -26,8 +26,8 @@ class TestUser(Base): age = Column(Integer) is_active = Column(Boolean, default=True) - class TestProduct(Base): - """Test product model for DML operations.""" + class Product(Base): + """Product model for DML operations testing.""" __tablename__ = "test_products_orm" @@ -478,7 +478,7 @@ def test_orm_insert_single_object(self, session_maker, conn): session.commit() # Create and insert a user using pure ORM - user = TestUser() + user = User() user.id = 100 user.name = "John Doe" user.email = "john@example.com" @@ -523,7 +523,7 @@ def test_orm_insert_multiple_objects_individually(self, session_maker, conn): session.commit() # Create and insert products using pure ORM - add individually - product1 = TestProduct() + product1 = Product() product1.id = 200 product1.name = "Laptop" product1.price = 999.99 @@ -532,7 +532,7 @@ def test_orm_insert_multiple_objects_individually(self, session_maker, conn): session.add(product1) session.commit() - product2 = TestProduct() + product2 = Product() product2.id = 201 product2.name = "Mouse" product2.price = 25.50 @@ -541,7 +541,7 @@ def test_orm_insert_multiple_objects_individually(self, session_maker, conn): session.add(product2) session.commit() - product3 = TestProduct() + product3 = Product() product3.id = 202 product3.name = "Keyboard" product3.price = 75.00 @@ -589,7 +589,7 @@ def test_orm_update_via_raw_sql(self, session_maker, conn): session.commit() # Create and insert initial user using ORM - user = TestUser() + user = User() user.id = 300 user.name = "Jane Smith" user.email = "jane@example.com" @@ -638,7 +638,7 @@ def test_orm_delete_via_raw_sql(self, session_maker, conn): session.commit() # Create and insert products using ORM - product1 = TestProduct() + product1 = Product() product1.id = 400 product1.name = "Monitor" product1.price = 299.99 @@ -647,7 +647,7 @@ def test_orm_delete_via_raw_sql(self, session_maker, conn): session.add(product1) session.commit() - product2 = TestProduct() + product2 = Product() product2.id = 401 product2.name = "Speaker" product2.price = 49.99 From 47dd71e465030bc4e63ab9e6255a7ac056a54444 Mon Sep 17 00:00:00 2001 From: Peng Ren Date: Tue, 30 Dec 2025 17:14:38 -0500 Subject: [PATCH 5/5] Fixed test case issue --- README.md | 40 +++++++++++++++++++++++++++++++++--- tests/conftest.py | 3 --- tests/test_sqlalchemy_dml.py | 25 +++++----------------- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index a8cb8e7..ddfacb1 100644 --- a/README.md +++ b/README.md @@ -216,7 +216,9 @@ Parameters are substituted into the MongoDB filter during execution, providing p ### INSERT Statements -PyMongoSQL supports inserting documents into MongoDB collections using PartiQL-style object and bag literals. +PyMongoSQL supports inserting documents into MongoDB collections using both PartiQL-style object literals and standard SQL INSERT VALUES syntax. + +#### PartiQL-Style Object Literals **Single Document** @@ -239,12 +241,44 @@ cursor.execute( ```python # Positional parameters using ? placeholders cursor.execute( - "INSERT INTO Music {'title': ?, 'artist': ?, 'year': ?}", + "INSERT INTO Music {'title': '?', 'artist': '?', 'year': '?'}", ["Song D", "Diana", 2020] ) ``` -> **Note**: For parameterized INSERT, use positional parameters (`?`). Named placeholders (`:name`) are supported for SELECT, UPDATE, and DELETE queries. +#### Standard SQL INSERT VALUES + +**Single Row with Column List** + +```python +cursor.execute( + "INSERT INTO Music (title, artist, year) VALUES ('Song E', 'Eve', 2022)" +) +``` + +**Multiple Rows** + +```python +cursor.execute( + "INSERT INTO Music (title, artist, year) VALUES ('Song F', 'Frank', 2023), ('Song G', 'Grace', 2024)" +) +``` + +**Parameterized INSERT VALUES** + +```python +# Positional parameters (?) +cursor.execute( + "INSERT INTO Music (title, artist, year) VALUES (?, ?, ?)", + ["Song H", "Henry", 2025] +) + +# Named parameters (:name) +cursor.execute( + "INSERT INTO Music (title, artist) VALUES (:title, :artist)", + {"title": "Song I", "artist": "Iris"} +) +``` ### UPDATE Statements diff --git a/tests/conftest.py b/tests/conftest.py index ce220d5..dc50af4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,9 +5,6 @@ from pymongosql.connection import Connection -# Silence SQLAlchemy 1.4 deprecation warnings in tests -os.environ.setdefault("SQLALCHEMY_SILENCE_UBER_WARNING", "1") - # Centralized test configuration sourced from environment to allow running tests # against remote MongoDB (e.g. Atlas) or local test instance. TEST_URI = os.environ.get("PYMONGOSQL_TEST_URI") or os.environ.get("MONGODB_URI") diff --git a/tests/test_sqlalchemy_dml.py b/tests/test_sqlalchemy_dml.py index b72bdc9..00b1951 100644 --- a/tests/test_sqlalchemy_dml.py +++ b/tests/test_sqlalchemy_dml.py @@ -43,18 +43,16 @@ class TestSQLAlchemyDML: def test_insert_single_row_explicit_columns(self, sqlalchemy_engine, conn): """Test INSERT with single row and explicit columns via SQLAlchemy.""" - with sqlalchemy_engine.connect() as connection: + with sqlalchemy_engine.begin() as connection: # Clean up test data first try: connection.execute(text("DELETE FROM test_insert_values")) - connection.commit() except Exception: pass # Insert single row with VALUES clause sql = "INSERT INTO test_insert_values (id, name, age) VALUES (1, 'Alice', 30)" connection.execute(text(sql)) - connection.commit() # Verify the insert result = connection.execute(text("SELECT id, name, age FROM test_insert_values WHERE id = 1")) @@ -72,22 +70,19 @@ def test_insert_single_row_explicit_columns(self, sqlalchemy_engine, conn): # Clean up connection.execute(text("DELETE FROM test_insert_values")) - connection.commit() def test_insert_multiple_rows_explicit_columns(self, sqlalchemy_engine, conn): """Test INSERT with multiple rows and explicit columns via SQLAlchemy.""" - with sqlalchemy_engine.connect() as connection: + with sqlalchemy_engine.begin() as connection: # Clean up test data first try: connection.execute(text("DELETE FROM test_insert_values")) - connection.commit() except Exception: pass # Insert multiple rows with VALUES clause sql = "INSERT INTO test_insert_values (id, name, age) VALUES (1, 'Alice', 30), (2, 'Bob', 25)" connection.execute(text(sql)) - connection.commit() # Verify the inserts result = connection.execute(text("SELECT id, name, age FROM test_insert_values ORDER BY id")) @@ -113,22 +108,19 @@ def test_insert_multiple_rows_explicit_columns(self, sqlalchemy_engine, conn): # Clean up connection.execute(text("DELETE FROM test_insert_values")) - connection.commit() def test_insert_single_row_implicit_columns(self, sqlalchemy_engine, conn): """Test INSERT with single row without column list via SQLAlchemy.""" - with sqlalchemy_engine.connect() as connection: + with sqlalchemy_engine.begin() as connection: # Clean up test data first try: connection.execute(text("DELETE FROM test_insert_implicit")) - connection.commit() except Exception: pass # Insert single row with VALUES clause (implicit columns) sql = "INSERT INTO test_insert_implicit VALUES (1, 'Alice', 30)" connection.execute(text(sql)) - connection.commit() # Verify the insert (auto-named columns: col0, col1, col2) result = connection.execute(text("SELECT col0, col1, col2 FROM test_insert_implicit WHERE col0 = 1")) @@ -146,22 +138,19 @@ def test_insert_single_row_implicit_columns(self, sqlalchemy_engine, conn): # Clean up connection.execute(text("DELETE FROM test_insert_implicit")) - connection.commit() def test_insert_with_null_values(self, sqlalchemy_engine, conn): """Test INSERT with NULL values via SQLAlchemy.""" - with sqlalchemy_engine.connect() as connection: + with sqlalchemy_engine.begin() as connection: # Clean up test data first try: connection.execute(text("DELETE FROM test_insert_null")) - connection.commit() except Exception: pass # Insert with NULL value sql = "INSERT INTO test_insert_null (id, name, email) VALUES (1, 'Alice', NULL)" connection.execute(text(sql)) - connection.commit() # Verify the insert result = connection.execute(text("SELECT id, name, email FROM test_insert_null WHERE id = 1")) @@ -179,22 +168,19 @@ def test_insert_with_null_values(self, sqlalchemy_engine, conn): # Clean up connection.execute(text("DELETE FROM test_insert_null")) - connection.commit() def test_insert_with_boolean_values(self, sqlalchemy_engine, conn): """Test INSERT with boolean values via SQLAlchemy.""" - with sqlalchemy_engine.connect() as connection: + with sqlalchemy_engine.begin() as connection: # Clean up test data first try: connection.execute(text("DELETE FROM test_insert_bool")) - connection.commit() except Exception: pass # Insert with boolean values sql = "INSERT INTO test_insert_bool (id, is_active, is_deleted) VALUES (1, TRUE, FALSE)" connection.execute(text(sql)) - connection.commit() # Verify the insert result = connection.execute(text("SELECT id, is_active, is_deleted FROM test_insert_bool WHERE id = 1")) @@ -212,7 +198,6 @@ def test_insert_with_boolean_values(self, sqlalchemy_engine, conn): # Clean up connection.execute(text("DELETE FROM test_insert_bool")) - connection.commit() def test_orm_table_insert_single_row(self, session_maker, conn): """Test INSERT VALUES with ORM table using raw SQL."""