From 2e52aaa30d8c611029bf2a8bfbd90c3858ce23bb Mon Sep 17 00:00:00 2001 From: Peng Ren Date: Sun, 19 Apr 2026 10:55:56 -0400 Subject: [PATCH 1/6] Add views in test dataset and implement get_view_names for sqlalchemy dialect --- pymongosql/__init__.py | 2 +- .../sqlalchemy_mongodb/sqlalchemy_dialect.py | 31 +- tests/data/sensor_readings.json | 86 +++ tests/run_test_server.py | 91 +++ tests/server_config.json | 10 +- tests/test_sqlalchemy_dialect.py | 538 ++++++------------ 6 files changed, 380 insertions(+), 378 deletions(-) create mode 100644 tests/data/sensor_readings.json diff --git a/pymongosql/__init__.py b/pymongosql/__init__.py index eefeaeb..64603b0 100644 --- a/pymongosql/__init__.py +++ b/pymongosql/__init__.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from .connection import Connection -__version__: str = "0.5.0" +__version__: str = "0.6.0" # Globals https://www.python.org/dev/peps/pep-0249/#globals apilevel: str = "2.0" diff --git a/pymongosql/sqlalchemy_mongodb/sqlalchemy_dialect.py b/pymongosql/sqlalchemy_mongodb/sqlalchemy_dialect.py index d5a3029..8c89cbf 100644 --- a/pymongosql/sqlalchemy_mongodb/sqlalchemy_dialect.py +++ b/pymongosql/sqlalchemy_mongodb/sqlalchemy_dialect.py @@ -300,9 +300,8 @@ def has_table(self, connection, table_name: str, schema: Optional[str] = None, * return False def get_table_names(self, connection, schema: Optional[str] = None, **kwargs) -> List[str]: - """Get list of collections (tables).""" + """Get list of collections (tables), excluding views.""" try: - # Use MongoDB listCollections command directly db_connection = connection.connection if hasattr(db_connection, "_client"): if schema: @@ -310,28 +309,24 @@ def get_table_names(self, connection, schema: Optional[str] = None, **kwargs) -> else: db = db_connection.database - # Use listCollections command - return db.list_collection_names() + return db.list_collection_names(filter={"type": {"$ne": "view"}}) except Exception as e: _logger.warning(f"Failed to get table names: {e}") return [] def get_view_names(self, connection, schema: Optional[str] = None, **kwargs) -> List[str]: - """Get list of views. - - MongoDB doesn't have traditional SQL views like relational databases. - Return empty list to satisfy SQLAlchemy and tools like Superset. - - Args: - connection: Database connection - schema: Optional schema/database name - **kwargs: Additional arguments + """Get list of MongoDB views.""" + try: + db_connection = connection.connection + if hasattr(db_connection, "_client"): + if schema: + db = db_connection._client[schema] + else: + db = db_connection.database - Returns: - Empty list as MongoDB doesn't support SQL views - """ - # MongoDB doesn't have traditional SQL views - # Return empty list to avoid NotImplementedError + return db.list_collection_names(filter={"type": "view"}) + except Exception as e: + _logger.warning(f"Failed to get view names: {e}") return [] def get_columns(self, connection, table_name: str, schema: Optional[str] = None, **kwargs) -> List[Dict[str, Any]]: diff --git a/tests/data/sensor_readings.json b/tests/data/sensor_readings.json new file mode 100644 index 0000000..4616185 --- /dev/null +++ b/tests/data/sensor_readings.json @@ -0,0 +1,86 @@ +[ + { + "sensor_id": "sensor_01", + "timestamp": {"$date": "2024-01-15T08:00:00Z"}, + "metadata": {"location": "warehouse_A", "type": "temperature"}, + "temperature": 22.5, + "humidity": 45.2 + }, + { + "sensor_id": "sensor_01", + "timestamp": {"$date": "2024-01-15T08:15:00Z"}, + "metadata": {"location": "warehouse_A", "type": "temperature"}, + "temperature": 22.8, + "humidity": 44.9 + }, + { + "sensor_id": "sensor_01", + "timestamp": {"$date": "2024-01-15T08:30:00Z"}, + "metadata": {"location": "warehouse_A", "type": "temperature"}, + "temperature": 23.1, + "humidity": 44.5 + }, + { + "sensor_id": "sensor_02", + "timestamp": {"$date": "2024-01-15T08:00:00Z"}, + "metadata": {"location": "warehouse_B", "type": "temperature"}, + "temperature": 19.3, + "humidity": 52.1 + }, + { + "sensor_id": "sensor_02", + "timestamp": {"$date": "2024-01-15T08:15:00Z"}, + "metadata": {"location": "warehouse_B", "type": "temperature"}, + "temperature": 19.5, + "humidity": 51.8 + }, + { + "sensor_id": "sensor_02", + "timestamp": {"$date": "2024-01-15T08:30:00Z"}, + "metadata": {"location": "warehouse_B", "type": "temperature"}, + "temperature": 19.8, + "humidity": 51.3 + }, + { + "sensor_id": "sensor_03", + "timestamp": {"$date": "2024-01-15T08:00:00Z"}, + "metadata": {"location": "office_1", "type": "environment"}, + "temperature": 21.0, + "humidity": 40.0 + }, + { + "sensor_id": "sensor_03", + "timestamp": {"$date": "2024-01-15T08:15:00Z"}, + "metadata": {"location": "office_1", "type": "environment"}, + "temperature": 21.3, + "humidity": 39.7 + }, + { + "sensor_id": "sensor_03", + "timestamp": {"$date": "2024-01-15T08:30:00Z"}, + "metadata": {"location": "office_1", "type": "environment"}, + "temperature": 21.6, + "humidity": 39.4 + }, + { + "sensor_id": "sensor_01", + "timestamp": {"$date": "2024-01-15T09:00:00Z"}, + "metadata": {"location": "warehouse_A", "type": "temperature"}, + "temperature": 23.5, + "humidity": 43.8 + }, + { + "sensor_id": "sensor_02", + "timestamp": {"$date": "2024-01-15T09:00:00Z"}, + "metadata": {"location": "warehouse_B", "type": "temperature"}, + "temperature": 20.1, + "humidity": 50.9 + }, + { + "sensor_id": "sensor_03", + "timestamp": {"$date": "2024-01-15T09:00:00Z"}, + "metadata": {"location": "office_1", "type": "environment"}, + "temperature": 22.0, + "humidity": 38.9 + } +] diff --git a/tests/run_test_server.py b/tests/run_test_server.py index 4c527be..6b24209 100644 --- a/tests/run_test_server.py +++ b/tests/run_test_server.py @@ -58,6 +58,9 @@ def load_config(): if "test_data_file" in config and not TEST_DATA_FILES: TEST_DATA_FILES = {"legacy": config["test_data_file"]} +# Time-series collection definitions +TIMESERIES_COLLECTIONS = config.get("timeseries_collections", {}) + def check_docker(): """Check if Docker is available and running""" @@ -244,6 +247,82 @@ def load_test_data(): return test_data +def _create_views(db): + """Create MongoDB views for testing""" + views = [ + { + "name": "active_users", + "viewOn": "users", + "pipeline": [ + {"$match": {"active": True}}, + {"$project": {"_id": 1, "name": 1, "email": 1, "age": 1, "balance": 1}}, + ], + }, + { + "name": "completed_orders", + "viewOn": "orders", + "pipeline": [ + {"$match": {"status": "completed"}}, + { + "$project": { + "_id": 1, + "user_id": 1, + "order_date": 1, + "total_amount": 1, + "currency": 1, + } + }, + ], + }, + { + "name": "in_stock_products", + "viewOn": "products", + "pipeline": [ + {"$match": {"in_stock": True}}, + {"$project": {"_id": 1, "name": 1, "price": 1, "category": 1, "quantity": 1}}, + ], + }, + { + "name": "orders_with_users", + "viewOn": "orders", + "pipeline": [ + { + "$lookup": { + "from": "users", + "localField": "user_id", + "foreignField": "_id", + "as": "user", + } + }, + {"$unwind": "$user"}, + { + "$project": { + "_id": 1, + "order_date": 1, + "status": 1, + "total_amount": 1, + "currency": 1, + "user_name": "$user.name", + "user_email": "$user.email", + } + }, + ], + }, + ] + + for view in views: + # Drop existing view if it exists + db[view["name"]].drop() + db.command( + { + "create": view["name"], + "viewOn": view["viewOn"], + "pipeline": view["pipeline"], + } + ) + print(f" Created view '{view['name']}' on '{view['viewOn']}'") + + def setup_test_data(): """Setup test data in MongoDB""" print("Setting up test data...") @@ -273,11 +352,23 @@ def setup_test_data(): # Drop existing collection db[collection_name].drop() + # Create time-series collection if configured + if collection_name in TIMESERIES_COLLECTIONS: + ts_opts = TIMESERIES_COLLECTIONS[collection_name] + db.create_collection( + collection_name, + timeseries=ts_opts, + ) + print(f" Created time-series collection '{collection_name}' (timeField={ts_opts['timeField']})") + # Insert new data db[collection_name].insert_many(test_data[collection_name]) count = db[collection_name].count_documents({}) print(f" Inserted {count} {collection_name}") + # Create MongoDB views + _create_views(db) + print("[SUCCESS] Test data setup completed successfully!") return True diff --git a/tests/server_config.json b/tests/server_config.json index 9a1288a..e81192d 100644 --- a/tests/server_config.json +++ b/tests/server_config.json @@ -25,6 +25,14 @@ "analytics": "data/analytics.json", "departments": "data/departments.json", "suppliers": "data/suppliers.json", - "user-orders": "data/user-orders.json" + "user-orders": "data/user-orders.json", + "sensor_readings": "data/sensor_readings.json" + }, + "timeseries_collections": { + "sensor_readings": { + "timeField": "timestamp", + "metaField": "metadata", + "granularity": "minutes" + } } } \ No newline at end of file diff --git a/tests/test_sqlalchemy_dialect.py b/tests/test_sqlalchemy_dialect.py index 1954193..a89ddbf 100644 --- a/tests/test_sqlalchemy_dialect.py +++ b/tests/test_sqlalchemy_dialect.py @@ -3,6 +3,8 @@ from typing import Callable from unittest.mock import Mock, patch +import pytest + # SQLAlchemy version compatibility try: import sqlalchemy @@ -43,12 +45,26 @@ class _TestBase(DeclarativeBase): # Prefix with _ to avoid pytest collection PyMongoSQLTypeCompiler, ) +# Known test collections and views set up by run_test_server.py +EXPECTED_COLLECTIONS = { + "users", + "products", + "categories", + "orders", + "analytics", + "departments", + "suppliers", + "user-orders", +} +EXPECTED_VIEWS = {"active_users", "completed_orders", "in_stock_products", "orders_with_users"} + +pytestmark = pytest.mark.skipif(not HAS_SQLALCHEMY, reason="SQLAlchemy not available") + -class TestPyMongoSQLDialect(unittest.TestCase): - """Test cases for the PyMongoSQL SQLAlchemy dialect.""" +class TestPyMongoSQLDialectUnit(unittest.TestCase): + """Pure unit tests for dialect properties that don't need MongoDB.""" def setUp(self): - """Set up test fixtures.""" if not HAS_SQLALCHEMY: self.skipTest("SQLAlchemy not available") self.dialect = PyMongoSQLDialect() @@ -60,18 +76,13 @@ def test_dialect_name(self): def test_dbapi(self): """Test DBAPI module reference.""" - # Test class method self.assertEqual(PyMongoSQLDialect.dbapi(), pymongosql) - - # Test import_dbapi class method (SQLAlchemy 2.x) self.assertEqual(PyMongoSQLDialect.import_dbapi(), pymongosql) - # Test instance access (should work even if SQLAlchemy interferes) try: result = self.dialect.dbapi() if callable(self.dialect.dbapi) else self.dialect._get_dbapi_module() self.assertEqual(result, pymongosql) except Exception: - # Fallback test - at least the class method should work self.assertEqual(PyMongoSQLDialect.dbapi(), pymongosql) def test_create_connect_args_basic(self): @@ -81,7 +92,6 @@ def test_create_connect_args_basic(self): self.assertEqual(args, []) self.assertIn("host", kwargs) - # The new implementation passes the complete MongoDB URI as host self.assertEqual(kwargs["host"], "mongodb://localhost:27017/testdb") def test_create_connect_args_with_auth(self): @@ -89,7 +99,6 @@ def test_create_connect_args_with_auth(self): test_url = url.make_url("mongodb://user:pass@localhost:27017/testdb") args, kwargs = self.dialect.create_connect_args(test_url) - # The new implementation passes the complete MongoDB URI with auth as host self.assertIn("host", kwargs) self.assertEqual(kwargs["host"], "mongodb://user:pass@localhost:27017/testdb") @@ -98,126 +107,27 @@ def test_create_connect_args_with_query_params(self): test_url = url.make_url("mongodb://localhost/testdb?ssl=true&replicaSet=rs0") args, kwargs = self.dialect.create_connect_args(test_url) - # The new implementation passes the complete MongoDB URI with query params as host self.assertIn("host", kwargs) self.assertIn("ssl=true", kwargs["host"]) self.assertIn("replicaSet=rs0", kwargs["host"]) def test_supports_features(self): """Test dialect feature support flags.""" - # Features MongoDB doesn't support self.assertFalse(self.dialect.supports_alter) self.assertFalse(self.dialect.supports_comments) self.assertFalse(self.dialect.supports_sequences) self.assertFalse(self.dialect.supports_native_enum) - # Features MongoDB does support self.assertTrue(self.dialect.supports_default_values) self.assertTrue(self.dialect.supports_empty_inserts) self.assertTrue(self.dialect.supports_multivalues_insert) self.assertTrue(self.dialect.supports_native_decimal) self.assertTrue(self.dialect.supports_native_boolean) - def test_has_table(self): - """Test table (collection) existence check using MongoDB operations.""" - from unittest.mock import MagicMock - - # Mock MongoDB connection structure - mock_conn = Mock() - mock_db_connection = Mock() - mock_client = MagicMock() # Use MagicMock for __getitem__ support - mock_db = Mock() - - mock_conn.connection = mock_db_connection - mock_db_connection._client = mock_client - mock_db_connection.database = mock_db - mock_db.list_collection_names.return_value = ["users", "products", "orders"] - - # Test existing table - self.assertTrue(self.dialect.has_table(mock_conn, "users")) - - # Test non-existing table - self.assertFalse(self.dialect.has_table(mock_conn, "nonexistent")) - - # Test with schema - mock_schema_db = Mock() - mock_client.__getitem__.return_value = mock_schema_db - mock_schema_db.list_collection_names.return_value = ["schema_users"] - self.assertTrue(self.dialect.has_table(mock_conn, "schema_users", schema="test_schema")) - - def test_get_table_names(self): - """Test getting collection names using MongoDB operations.""" - from unittest.mock import MagicMock - - # Mock MongoDB connection structure - mock_conn = Mock() - mock_db_connection = Mock() - mock_client = MagicMock() # Use MagicMock for __getitem__ support - mock_db = Mock() - - mock_conn.connection = mock_db_connection - mock_db_connection._client = mock_client - mock_db_connection.database = mock_db - mock_db.list_collection_names.return_value = ["users", "products", "orders"] - - tables = self.dialect.get_table_names(mock_conn) - expected = ["users", "products", "orders"] - self.assertEqual(tables, expected) - - # Test with schema - mock_schema_db = Mock() - mock_client.__getitem__.return_value = mock_schema_db - mock_schema_db.list_collection_names.return_value = ["schema_table1", "schema_table2"] - schema_tables = self.dialect.get_table_names(mock_conn, schema="test_schema") - self.assertEqual(schema_tables, ["schema_table1", "schema_table2"]) - - @patch("bson.ObjectId") - def test_get_columns(self, mock_objectid): - """Test getting column information using MongoDB document sampling.""" - from datetime import datetime - from unittest.mock import MagicMock - - # Mock MongoDB connection structure - mock_conn = Mock() - mock_db_connection = Mock() - mock_client = Mock() - mock_db = MagicMock() # Use MagicMock for __getitem__ support - mock_collection = Mock() - - mock_conn.connection = mock_db_connection - mock_db_connection._client = mock_client - mock_db_connection.database = mock_db - mock_db.__getitem__.return_value = mock_collection - - # Mock sample documents - sample_docs = [ - {"_id": "507f1f77bcf86cd799439011", "name": "John", "age": 25, "active": True}, - {"_id": "507f1f77bcf86cd799439012", "name": "Jane", "email": "jane@test.com", "score": 95.5}, - {"_id": "507f1f77bcf86cd799439013", "created_at": datetime.now(), "tags": ["python", "mongodb"]}, - ] - mock_collection.find.return_value.limit.return_value = sample_docs - - columns = self.dialect.get_columns(mock_conn, "users") - - # Should have inferred columns from sample documents - self.assertGreater(len(columns), 0) - - # Check _id is always included and not nullable - id_column = next((col for col in columns if col["name"] == "_id"), None) - self.assertIsNotNone(id_column) - self.assertFalse(id_column["nullable"]) - - # Test fallback for empty collection - mock_collection.find.return_value.limit.return_value = [] - fallback_columns = self.dialect.get_columns(mock_conn, "empty_collection") - self.assertEqual(len(fallback_columns), 1) - self.assertEqual(fallback_columns[0]["name"], "_id") - def test_get_pk_constraint(self): """Test primary key constraint info.""" mock_conn = Mock() pk_info = self.dialect.get_pk_constraint(mock_conn, "users") - self.assertEqual(pk_info["constrained_columns"], ["_id"]) self.assertEqual(pk_info["name"], "pk_id") @@ -225,130 +135,12 @@ def test_get_foreign_keys(self): """Test foreign key constraints (should be empty for MongoDB).""" mock_conn = Mock() fks = self.dialect.get_foreign_keys(mock_conn, "users") - self.assertEqual(fks, []) - def test_get_indexes(self): - """Test getting index information using MongoDB index_information.""" - from unittest.mock import MagicMock - - # Mock MongoDB connection structure - mock_conn = Mock() - mock_db_connection = Mock() - mock_client = Mock() - mock_db = MagicMock() # Use MagicMock for __getitem__ support - mock_collection = Mock() - - mock_conn.connection = mock_db_connection - mock_db_connection._client = mock_client - mock_db_connection.database = mock_db - mock_db.__getitem__.return_value = mock_collection - - # Mock index information - mock_index_info = { - "_id_": {"key": [("_id", 1)], "unique": False}, # _id is implicit unique - "email_1": {"key": [("email", 1)], "unique": True}, - "name_text": {"key": [("name", "text")], "unique": False}, - } - mock_collection.index_information.return_value = mock_index_info - - indexes = self.dialect.get_indexes(mock_conn, "users") - - self.assertEqual(len(indexes), 3) - - # Check _id index - id_index = next((idx for idx in indexes if idx["name"] == "_id_"), None) - self.assertIsNotNone(id_index) - self.assertEqual(id_index["column_names"], ["_id"]) - - # Check email index - email_index = next((idx for idx in indexes if idx["name"] == "email_1"), None) - self.assertIsNotNone(email_index) - self.assertTrue(email_index["unique"]) - self.assertEqual(email_index["column_names"], ["email"]) - - def test_get_schema_names(self): - """Test getting database names using MongoDB listDatabases command.""" - # Mock MongoDB connection structure - mock_conn = Mock() - mock_db_connection = Mock() - mock_client = Mock() - mock_admin_db = Mock() - - mock_conn.connection = mock_db_connection - mock_db_connection._client = mock_client - mock_client.admin = mock_admin_db - - # Mock listDatabases result - mock_admin_db.command.return_value = { - "databases": [ - {"name": "admin", "sizeOnDisk": 32768}, - {"name": "config", "sizeOnDisk": 12288}, - {"name": "myapp", "sizeOnDisk": 65536}, - {"name": "test", "sizeOnDisk": 8192}, - ] - } - - schemas = self.dialect.get_schema_names(mock_conn) - expected = ["admin", "config", "myapp", "test"] - self.assertEqual(schemas, expected) - - # Verify the correct MongoDB command was called - mock_admin_db.command.assert_called_with("listDatabases") - - def test_get_schema_names_fallback(self): - """Test get_schema_names fallback when MongoDB operation fails.""" - # Mock connection that raises an exception - mock_conn = Mock() - mock_conn.connection.side_effect = Exception("Connection error") - - schemas = self.dialect.get_schema_names(mock_conn) - self.assertEqual(schemas, ["default"]) - - def test_do_ping(self): - """Test connection ping using MongoDB native ping command.""" - # Mock successful connection - mock_conn = Mock() - mock_conn.test_connection.return_value = True - - result = self.dialect.do_ping(mock_conn) - self.assertTrue(result) - - # Test fallback to direct client ping - mock_conn_no_test = Mock() - mock_conn_no_test.test_connection = None - mock_client = Mock() - mock_admin_db = Mock() - mock_conn_no_test._client = mock_client - mock_client.admin = mock_admin_db - - result_fallback = self.dialect.do_ping(mock_conn_no_test) - self.assertTrue(result_fallback) - mock_admin_db.command.assert_called_with("ping") - - def test_do_ping_failure(self): - """Test do_ping when connection fails.""" - # Mock failed connection - mock_conn = Mock() - mock_conn.test_connection.return_value = False - - result = self.dialect.do_ping(mock_conn) - self.assertFalse(result) - - # Test fallback failure - connection without test_connection method - mock_conn_error = Mock() - del mock_conn_error.test_connection # Remove the attribute entirely - mock_conn_error._client = Mock() - mock_conn_error._client.admin.command.side_effect = Exception("Connection failed") - - result_error = self.dialect.do_ping(mock_conn_error) - self.assertFalse(result_error) - def test_infer_bson_type(self): """Test BSON type inference from Python values.""" from datetime import datetime - # Test various Python types test_cases = [ ("test string", "string"), (42, "int"), @@ -363,137 +155,167 @@ def test_infer_bson_type(self): for value, expected_type in test_cases: with self.subTest(value=value, expected=expected_type): - inferred_type = self.dialect._infer_bson_type(value) - self.assertEqual(inferred_type, expected_type) - - def test_error_handling(self): - """Test error handling and fallback behavior for all methods.""" - # Mock connection that fails when trying to access MongoDB operations - mock_conn = Mock() - mock_db_connection = Mock() - mock_conn.connection = mock_db_connection - - # Make hasattr check fail or make database operations fail - mock_db_connection._client = None # This makes hasattr(_client) return False - # Or we can make database operations fail by making database.list_collection_names() fail - mock_db = Mock() - mock_db_connection.database = mock_db - mock_db.list_collection_names.side_effect = Exception("MongoDB error") - - # Test has_table fallback - result = self.dialect.has_table(mock_conn, "test_table") - self.assertFalse(result) - - # Test get_table_names fallback - tables = self.dialect.get_table_names(mock_conn) - self.assertEqual(tables, []) - - # Test get_columns fallback - columns = self.dialect.get_columns(mock_conn, "test_table") - self.assertEqual(len(columns), 1) - self.assertEqual(columns[0]["name"], "_id") - - # Test get_indexes fallback - indexes = self.dialect.get_indexes(mock_conn, "test_table") - self.assertEqual(len(indexes), 1) - self.assertEqual(indexes[0]["name"], "_id_") - self.assertTrue(indexes[0]["unique"]) - - def test_schema_operations_with_schema_parameter(self): - """Test operations when schema parameter is provided.""" - from unittest.mock import MagicMock - - # Mock MongoDB connection structure - mock_conn = Mock() - mock_db_connection = Mock() - mock_client = MagicMock() # Use MagicMock for __getitem__ support - mock_schema_db = MagicMock() # Use MagicMock for __getitem__ support - mock_collection = Mock() - - mock_conn.connection = mock_db_connection - mock_db_connection._client = mock_client - mock_client.__getitem__.return_value = mock_schema_db - mock_schema_db.__getitem__.return_value = mock_collection - mock_schema_db.list_collection_names.return_value = ["table1", "table2"] - - # Test has_table with schema - result = self.dialect.has_table(mock_conn, "table1", schema="test_schema") - self.assertTrue(result) - mock_client.__getitem__.assert_called_with("test_schema") - - # Test get_table_names with schema - tables = self.dialect.get_table_names(mock_conn, schema="test_schema") - self.assertEqual(tables, ["table1", "table2"]) - - # Test get_columns with schema - mock_collection.find.return_value.limit.return_value = [{"_id": "123", "name": "test"}] - columns = self.dialect.get_columns(mock_conn, "table1", schema="test_schema") - self.assertGreater(len(columns), 0) - mock_schema_db.__getitem__.assert_called_with("table1") - - def test_superset_integration_workflow(self): - """Test the complete workflow that Apache Superset would use.""" - from unittest.mock import MagicMock - - # Mock complete MongoDB connection for Superset workflow - mock_conn = Mock() - mock_db_connection = Mock() - mock_client = MagicMock() - mock_db = MagicMock() # Use MagicMock for __getitem__ support - mock_admin_db = Mock() - mock_collection = Mock() - - # Wire up the mock chain - mock_conn.connection = mock_db_connection - mock_db_connection._client = mock_client - mock_db_connection.database = mock_db - mock_client.admin = mock_admin_db - mock_db.__getitem__.return_value = mock_collection - - # Set up realistic responses - mock_conn.test_connection = Mock(return_value=True) - mock_admin_db.command.return_value = {"databases": [{"name": "myapp"}, {"name": "analytics"}]} - mock_db.list_collection_names.return_value = ["users", "orders", "products"] - mock_collection.find.return_value.limit.return_value = [ - {"_id": "1", "name": "Test User", "email": "test@example.com", "age": 30} - ] - mock_collection.index_information.return_value = { - "_id_": {"key": [("_id", 1)], "unique": False}, - "email_1": {"key": [("email", 1)], "unique": True}, - } - - # Step 1: Connection testing (what Superset does first) - ping_success = self.dialect.do_ping(mock_conn) - self.assertTrue(ping_success, "Connection ping should succeed") - - # Step 2: Discover available databases/schemas - schemas = self.dialect.get_schema_names(mock_conn) - self.assertEqual(schemas, ["myapp", "analytics"], "Should discover databases") - - # Step 3: List tables/collections in default database - tables = self.dialect.get_table_names(mock_conn) - self.assertEqual(tables, ["users", "orders", "products"], "Should list collections") - - # Step 4: Check if specific table exists - self.assertTrue(self.dialect.has_table(mock_conn, "users"), "Should find existing table") - self.assertFalse(self.dialect.has_table(mock_conn, "logs"), "Should not find non-existing table") - - # Step 5: Get column information for table introspection - columns = self.dialect.get_columns(mock_conn, "users") - self.assertGreater(len(columns), 0, "Should discover columns from document sampling") - - # Verify required _id column exists and is not nullable - id_column = next((col for col in columns if col["name"] == "_id"), None) - self.assertIsNotNone(id_column, "_id column should exist") - self.assertFalse(id_column["nullable"], "_id should not be nullable") - - # Step 6: Get index information for performance optimization - indexes = self.dialect.get_indexes(mock_conn, "users") - self.assertGreater(len(indexes), 0, "Should discover indexes") - - # Verify _id index exists - id_index = next((idx for idx in indexes if idx["name"] == "_id_"), None) - self.assertIsNotNone(id_index, "_id index should exist") + self.assertEqual(self.dialect._infer_bson_type(value), expected_type) + + +class TestPyMongoSQLDialectIntegration: + """Integration tests for dialect introspection against real MongoDB.""" + + def test_has_table_existing(self, sqlalchemy_engine): + """Test that existing collections are found.""" + dialect = sqlalchemy_engine.dialect + with sqlalchemy_engine.connect() as conn: + assert dialect.has_table(conn, "users") is True + assert dialect.has_table(conn, "products") is True + assert dialect.has_table(conn, "orders") is True + + def test_has_table_nonexistent(self, sqlalchemy_engine): + """Test that non-existing collections return False.""" + dialect = sqlalchemy_engine.dialect + with sqlalchemy_engine.connect() as conn: + assert dialect.has_table(conn, "nonexistent_xyz") is False + + def test_get_table_names(self, sqlalchemy_engine): + """Test listing collections excludes views.""" + dialect = sqlalchemy_engine.dialect + with sqlalchemy_engine.connect() as conn: + tables = dialect.get_table_names(conn) + + assert isinstance(tables, list) + # Should contain known test collections + for collection in EXPECTED_COLLECTIONS: + assert collection in tables, f"Expected collection '{collection}' not found in {tables}" + # Should NOT contain views + for view in EXPECTED_VIEWS: + assert view not in tables, f"View '{view}' should not appear in table names" + + def test_get_view_names(self, sqlalchemy_engine): + """Test listing views returns only views.""" + dialect = sqlalchemy_engine.dialect + with sqlalchemy_engine.connect() as conn: + views = dialect.get_view_names(conn) + + assert isinstance(views, list) + # Should contain known test views + for view in EXPECTED_VIEWS: + assert view in views, f"Expected view '{view}' not found in {views}" + # Should NOT contain regular collections + for collection in EXPECTED_COLLECTIONS: + assert collection not in views, f"Collection '{collection}' should not appear in view names" + + def test_get_columns_users(self, sqlalchemy_engine): + """Test column inference from users collection.""" + dialect = sqlalchemy_engine.dialect + with sqlalchemy_engine.connect() as conn: + columns = dialect.get_columns(conn, "users") + + assert len(columns) > 0 + col_names = [c["name"] for c in columns] + + # Users collection should have these fields + assert "_id" in col_names + assert "name" in col_names + assert "email" in col_names + + # _id should not be nullable + id_col = next(c for c in columns if c["name"] == "_id") + assert id_col["nullable"] is False + + def test_get_columns_products(self, sqlalchemy_engine): + """Test column inference from products collection.""" + dialect = sqlalchemy_engine.dialect + with sqlalchemy_engine.connect() as conn: + columns = dialect.get_columns(conn, "products") + + col_names = [c["name"] for c in columns] + assert "_id" in col_names + assert "name" in col_names + assert "price" in col_names + assert "category" in col_names + + def test_get_columns_view(self, sqlalchemy_engine): + """Test column inference works on views too.""" + dialect = sqlalchemy_engine.dialect + with sqlalchemy_engine.connect() as conn: + columns = dialect.get_columns(conn, "active_users") + + col_names = [c["name"] for c in columns] + assert "_id" in col_names + assert "name" in col_names + assert "email" in col_names + + def test_get_indexes(self, sqlalchemy_engine): + """Test getting index information from a real collection.""" + dialect = sqlalchemy_engine.dialect + with sqlalchemy_engine.connect() as conn: + indexes = dialect.get_indexes(conn, "users") + + assert len(indexes) >= 1 + # Every collection has at least the _id index + id_index = next((idx for idx in indexes if idx["name"] == "_id_"), None) + assert id_index is not None + assert "_id" in id_index["column_names"] + + def test_get_schema_names(self, sqlalchemy_engine): + """Test listing databases.""" + dialect = sqlalchemy_engine.dialect + with sqlalchemy_engine.connect() as conn: + schemas = dialect.get_schema_names(conn) + + assert isinstance(schemas, list) + assert len(schemas) > 0 + # test_db should be among the databases + assert "test_db" in schemas + + def test_do_ping(self, sqlalchemy_engine): + """Test connection ping against real MongoDB.""" + dialect = sqlalchemy_engine.dialect + with sqlalchemy_engine.connect() as conn: + result = dialect.do_ping(conn.connection) + assert result is True + + def test_superset_workflow(self, sqlalchemy_engine): + """Test the complete introspection workflow Superset performs.""" + dialect = sqlalchemy_engine.dialect + with sqlalchemy_engine.connect() as conn: + # Step 1: Ping + assert dialect.do_ping(conn.connection) is True + + # Step 2: Discover schemas + schemas = dialect.get_schema_names(conn) + assert len(schemas) > 0 + + # Step 3: List tables (should not include views) + tables = dialect.get_table_names(conn) + assert "users" in tables + for view in EXPECTED_VIEWS: + assert view not in tables + + # Step 4: List views + views = dialect.get_view_names(conn) + for view in EXPECTED_VIEWS: + assert view in views + + # Step 5: Check table existence + assert dialect.has_table(conn, "users") is True + assert dialect.has_table(conn, "nonexistent_xyz") is False + + # Step 6: Get columns + columns = dialect.get_columns(conn, "users") + assert len(columns) > 0 + id_col = next(c for c in columns if c["name"] == "_id") + assert id_col["nullable"] is False + + # Step 7: Get indexes + indexes = dialect.get_indexes(conn, "users") + assert len(indexes) >= 1 + + # Step 8: PK and FK constraints + pk = dialect.get_pk_constraint(conn, "users") + assert pk["constrained_columns"] == ["_id"] + + fks = dialect.get_foreign_keys(conn, "users") + assert fks == [] class TestPyMongoSQLCompilers(unittest.TestCase): From 6d4b75849a4b9c6b8391d7c887aace2ec5c1cc2c Mon Sep 17 00:00:00 2001 From: Peng Ren Date: Sun, 19 Apr 2026 11:06:05 -0400 Subject: [PATCH 2/6] Adjust CI strategy --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a38f3fb..dcb5077 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI Tests on: push: - branches: [ main, "*.*.*" ] + branches: [ "feat/**", "fix/**", "chore/**", "refactor/**" ] pull_request: branches: [ main ] workflow_call: From d80a8ca88527de21debb1fb7810653d61596d40c Mon Sep 17 00:00:00 2001 From: Peng Ren Date: Sun, 19 Apr 2026 11:45:15 -0400 Subject: [PATCH 3/6] Support view creation with SQL --- pymongosql/executor.py | 118 +++++++++- pymongosql/sql/partiql/PartiQLParser.g4 | 2 + pymongosql/sql/partiql/PartiQLParser.py | 65 ++++++ .../sql/partiql/PartiQLParserListener.py | 18 ++ .../sql/partiql/PartiQLParserVisitor.py | 10 + pymongosql/sql/view_builder.py | 46 ++++ tests/test_ddl_view.py | 218 ++++++++++++++++++ 7 files changed, 476 insertions(+), 1 deletion(-) create mode 100644 pymongosql/sql/view_builder.py create mode 100644 tests/test_ddl_view.py diff --git a/pymongosql/executor.py b/pymongosql/executor.py index b1e7615..12ac7a6 100644 --- a/pymongosql/executor.py +++ b/pymongosql/executor.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import logging +import re from abc import ABC, abstractmethod from dataclasses import dataclass from typing import Any, Dict, Optional, Sequence, Union @@ -14,6 +15,7 @@ from .sql.parser import SQLParser from .sql.query_builder import QueryExecutionPlan from .sql.update_builder import UpdateExecutionPlan +from .sql.view_builder import ViewExecutionPlan _logger = logging.getLogger(__name__) @@ -642,10 +644,124 @@ def execute( return self._execute_execution_plan(self._execution_plan, connection, parameters) +class ViewExecution(ExecutionStrategy): + """Execution strategy for view statements (CREATE VIEW, DROP VIEW).""" + + _DDL_PATTERN = re.compile( + r"^\s*(CREATE\s+VIEW|DROP\s+VIEW)\b", + re.IGNORECASE, + ) + + @property + def execution_plan(self) -> ViewExecutionPlan: + return self._execution_plan + + def supports(self, context: ExecutionContext) -> bool: + return bool(self._DDL_PATTERN.match(context.query)) + + def _parse_sql(self, sql: str) -> ViewExecutionPlan: + normalized = " ".join(sql.split()) + + # CREATE VIEW view_name ON collection_name AS 'pipeline_json' + create_match = re.match( + r"CREATE\s+VIEW\s+(\w+)\s+ON\s+(\w+)\s+AS\s+'(.*)'", + normalized, + re.IGNORECASE | re.DOTALL, + ) + if create_match: + import json + + view_name = create_match.group(1) + source_collection = create_match.group(2) + pipeline_str = create_match.group(3) + try: + pipeline = json.loads(pipeline_str) + except json.JSONDecodeError as e: + raise SqlSyntaxError(f"Invalid pipeline JSON in CREATE VIEW: {e}") + + if not isinstance(pipeline, list): + raise SqlSyntaxError("Pipeline must be a JSON array") + + return ViewExecutionPlan( + collection=view_name, + ddl_type="create_view", + view_on=source_collection, + pipeline=pipeline, + ) + + # DROP VIEW view_name + drop_match = re.match( + r"DROP\s+VIEW\s+(\w+)\s*$", + normalized, + re.IGNORECASE, + ) + if drop_match: + view_name = drop_match.group(1) + return ViewExecutionPlan( + collection=view_name, + ddl_type="drop_view", + ) + + raise SqlSyntaxError(f"Unsupported DDL statement: {sql}") + + def _execute_execution_plan( + self, + execution_plan: ViewExecutionPlan, + connection: Any = None, + parameters: Optional[Union[Sequence[Any], Dict[str, Any]]] = None, + ) -> Optional[Dict[str, Any]]: + try: + if not connection: + raise OperationalError("No connection provided") + + db = connection.database + + if execution_plan.ddl_type == "create_view": + command = { + "create": execution_plan.collection, + "viewOn": execution_plan.view_on, + "pipeline": execution_plan.pipeline, + } + _logger.debug(f"Executing MongoDB create view command: {command}") + return _run_db_command(db, command, connection, "create view") + + elif execution_plan.ddl_type == "drop_view": + # MongoDB drops views with the regular drop command + command = {"drop": execution_plan.collection} + _logger.debug(f"Executing MongoDB drop view command: {command}") + return _run_db_command(db, command, connection, "drop view") + + else: + raise ProgrammingError(f"Unknown DDL type: {execution_plan.ddl_type}") + + except PyMongoError as e: + _logger.error(f"MongoDB DDL execution failed: {e}") + raise DatabaseError(f"DDL execution failed: {e}") + except (ProgrammingError, DatabaseError, OperationalError): + raise + except Exception as e: + _logger.error(f"Unexpected error during DDL execution: {e}") + raise OperationalError(f"DDL execution error: {e}") + + def execute( + self, + context: ExecutionContext, + connection: Any, + parameters: Optional[Union[Sequence[Any], Dict[str, Any]]] = None, + ) -> Optional[Dict[str, Any]]: + _logger.debug(f"Using DDL execution for query: {context.query[:100]}") + self._execution_plan = self._parse_sql(context.query) + + if not self._execution_plan.validate(): + raise SqlSyntaxError("Generated DDL plan is invalid") + + return self._execute_execution_plan(self._execution_plan, connection, parameters) + + class ExecutionPlanFactory: """Factory for creating appropriate execution strategy based on query context""" - _strategies = [StandardQueryExecution(), InsertExecution(), UpdateExecution(), DeleteExecution()] + _strategies = [ViewExecution(), StandardQueryExecution(), InsertExecution(), UpdateExecution(), DeleteExecution()] @classmethod def get_strategy(cls, context: ExecutionContext) -> ExecutionStrategy: diff --git a/pymongosql/sql/partiql/PartiQLParser.g4 b/pymongosql/sql/partiql/PartiQLParser.g4 index 198625d..0c98eeb 100644 --- a/pymongosql/sql/partiql/PartiQLParser.g4 +++ b/pymongosql/sql/partiql/PartiQLParser.g4 @@ -86,11 +86,13 @@ ddl createCommand : CREATE TABLE qualifiedName ( PAREN_LEFT tableDef PAREN_RIGHT )? # CreateTable | CREATE INDEX ON symbolPrimitive PAREN_LEFT pathSimple ( COMMA pathSimple )* PAREN_RIGHT # CreateIndex + | CREATE VIEW symbolPrimitive ON symbolPrimitive AS LITERAL_STRING # CreateView ; dropCommand : DROP TABLE qualifiedName # DropTable | DROP INDEX target=symbolPrimitive ON on=symbolPrimitive # DropIndex + | DROP VIEW symbolPrimitive # DropView ; tableDef diff --git a/pymongosql/sql/partiql/PartiQLParser.py b/pymongosql/sql/partiql/PartiQLParser.py index dd6a02a..73369e8 100644 --- a/pymongosql/sql/partiql/PartiQLParser.py +++ b/pymongosql/sql/partiql/PartiQLParser.py @@ -2542,6 +2542,43 @@ def accept(self, visitor:ParseTreeVisitor): return visitor.visitChildren(self) + class CreateViewContext(CreateCommandContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a PartiQLParser.CreateCommandContext + super().__init__(parser) + self.copyFrom(ctx) + + def CREATE(self): + return self.getToken(PartiQLParser.CREATE, 0) + def VIEW(self): + return self.getToken(PartiQLParser.VIEW, 0) + def ON(self): + return self.getToken(PartiQLParser.ON, 0) + def AS(self): + return self.getToken(PartiQLParser.AS, 0) + def symbolPrimitive(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(PartiQLParser.SymbolPrimitiveContext) + else: + return self.getTypedRuleContext(PartiQLParser.SymbolPrimitiveContext,i) + + def LITERAL_STRING(self): + return self.getToken(PartiQLParser.LITERAL_STRING, 0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterCreateView" ): + listener.enterCreateView(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitCreateView" ): + listener.exitCreateView(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitCreateView" ): + return visitor.visitCreateView(self) + else: + return visitor.visitChildren(self) + def createCommand(self): @@ -2698,6 +2735,34 @@ def accept(self, visitor:ParseTreeVisitor): return visitor.visitChildren(self) + class DropViewContext(DropCommandContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a PartiQLParser.DropCommandContext + super().__init__(parser) + self.copyFrom(ctx) + + def DROP(self): + return self.getToken(PartiQLParser.DROP, 0) + def VIEW(self): + return self.getToken(PartiQLParser.VIEW, 0) + def symbolPrimitive(self): + return self.getTypedRuleContext(PartiQLParser.SymbolPrimitiveContext,0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterDropView" ): + listener.enterDropView(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitDropView" ): + listener.exitDropView(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitDropView" ): + return visitor.visitDropView(self) + else: + return visitor.visitChildren(self) + + def dropCommand(self): diff --git a/pymongosql/sql/partiql/PartiQLParserListener.py b/pymongosql/sql/partiql/PartiQLParserListener.py index 0822286..c227691 100644 --- a/pymongosql/sql/partiql/PartiQLParserListener.py +++ b/pymongosql/sql/partiql/PartiQLParserListener.py @@ -188,6 +188,15 @@ def exitCreateIndex(self, ctx:PartiQLParser.CreateIndexContext): pass + # Enter a parse tree produced by PartiQLParser#CreateView. + def enterCreateView(self, ctx:PartiQLParser.CreateViewContext): + pass + + # Exit a parse tree produced by PartiQLParser#CreateView. + def exitCreateView(self, ctx:PartiQLParser.CreateViewContext): + pass + + # Enter a parse tree produced by PartiQLParser#DropTable. def enterDropTable(self, ctx:PartiQLParser.DropTableContext): pass @@ -206,6 +215,15 @@ def exitDropIndex(self, ctx:PartiQLParser.DropIndexContext): pass + # Enter a parse tree produced by PartiQLParser#DropView. + def enterDropView(self, ctx:PartiQLParser.DropViewContext): + pass + + # Exit a parse tree produced by PartiQLParser#DropView. + def exitDropView(self, ctx:PartiQLParser.DropViewContext): + pass + + # Enter a parse tree produced by PartiQLParser#tableDef. def enterTableDef(self, ctx:PartiQLParser.TableDefContext): pass diff --git a/pymongosql/sql/partiql/PartiQLParserVisitor.py b/pymongosql/sql/partiql/PartiQLParserVisitor.py index 363c054..b7ab7dd 100644 --- a/pymongosql/sql/partiql/PartiQLParserVisitor.py +++ b/pymongosql/sql/partiql/PartiQLParserVisitor.py @@ -109,6 +109,11 @@ def visitCreateIndex(self, ctx:PartiQLParser.CreateIndexContext): return self.visitChildren(ctx) + # Visit a parse tree produced by PartiQLParser#CreateView. + def visitCreateView(self, ctx:PartiQLParser.CreateViewContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by PartiQLParser#DropTable. def visitDropTable(self, ctx:PartiQLParser.DropTableContext): return self.visitChildren(ctx) @@ -119,6 +124,11 @@ def visitDropIndex(self, ctx:PartiQLParser.DropIndexContext): return self.visitChildren(ctx) + # Visit a parse tree produced by PartiQLParser#DropView. + def visitDropView(self, ctx:PartiQLParser.DropViewContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by PartiQLParser#tableDef. def visitTableDef(self, ctx:PartiQLParser.TableDefContext): return self.visitChildren(ctx) diff --git a/pymongosql/sql/view_builder.py b/pymongosql/sql/view_builder.py new file mode 100644 index 0000000..785d764 --- /dev/null +++ b/pymongosql/sql/view_builder.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +import logging +from dataclasses import dataclass, field +from typing import Any, Dict, List, Optional + +from .builder import ExecutionPlan + +_logger = logging.getLogger(__name__) + + +@dataclass +class ViewExecutionPlan(ExecutionPlan): + """Execution plan for view statements (CREATE VIEW, DROP VIEW).""" + + ddl_type: str = "" # "create_view" or "drop_view" + view_on: Optional[str] = None # Source collection for CREATE VIEW + pipeline: Optional[List[Dict[str, Any]]] = field(default_factory=list) + + def to_dict(self) -> Dict[str, Any]: + result = { + "ddl_type": self.ddl_type, + "collection": self.collection, + } + if self.ddl_type == "create_view": + result["view_on"] = self.view_on + result["pipeline"] = self.pipeline + return result + + def validate(self) -> bool: + errors = self.validate_base() + + if not self.ddl_type: + errors.append("DDL type is required") + + if self.ddl_type == "create_view": + if not self.view_on: + errors.append("Source collection (ON) is required for CREATE VIEW") + if self.pipeline is None: + errors.append("Pipeline (AS) is required for CREATE VIEW") + + if errors: + for err in errors: + _logger.warning(f"View plan validation error: {err}") + return False + + return True diff --git a/tests/test_ddl_view.py b/tests/test_ddl_view.py new file mode 100644 index 0000000..fa745c9 --- /dev/null +++ b/tests/test_ddl_view.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +"""Tests for CREATE VIEW and DROP VIEW DDL statements.""" +import json + +import pytest + +from pymongosql.error import SqlSyntaxError +from pymongosql.executor import ExecutionContext, ExecutionPlanFactory, ViewExecution +from pymongosql.sql.view_builder import ViewExecutionPlan + + +class TestDDLParserUnit: + """Unit tests for DDL SQL parsing.""" + + def setup_method(self): + self.strategy = ViewExecution() + + def test_supports_create_view(self): + ctx = ExecutionContext("CREATE VIEW my_view ON users AS '[]'") + assert self.strategy.supports(ctx) + + def test_supports_create_view_case_insensitive(self): + ctx = ExecutionContext("create view my_view ON users AS '[]'") + assert self.strategy.supports(ctx) + + def test_supports_drop_view(self): + ctx = ExecutionContext("DROP VIEW my_view") + assert self.strategy.supports(ctx) + + def test_does_not_support_select(self): + ctx = ExecutionContext("SELECT * FROM users") + assert not self.strategy.supports(ctx) + + def test_does_not_support_create_table(self): + ctx = ExecutionContext("CREATE TABLE foo (id INT)") + assert not self.strategy.supports(ctx) + + def test_parse_create_view_simple(self): + plan = self.strategy._parse_sql('CREATE VIEW filtered_users ON users AS \'[{"$match": {"status": "active"}}]\'') + assert isinstance(plan, ViewExecutionPlan) + assert plan.ddl_type == "create_view" + assert plan.collection == "filtered_users" + assert plan.view_on == "users" + assert plan.pipeline == [{"$match": {"status": "active"}}] + assert plan.validate() + + def test_parse_create_view_empty_pipeline(self): + plan = self.strategy._parse_sql("CREATE VIEW every_user ON users AS '[]'") + assert plan.ddl_type == "create_view" + assert plan.collection == "every_user" + assert plan.view_on == "users" + assert plan.pipeline == [] + assert plan.validate() + + def test_parse_create_view_complex_pipeline(self): + pipeline = [ + {"$lookup": {"from": "orders", "localField": "_id", "foreignField": "user_id", "as": "orders"}}, + {"$match": {"status": "active"}}, + ] + plan = self.strategy._parse_sql(f"CREATE VIEW joined_user_orders ON users AS '{json.dumps(pipeline)}'") + assert plan.pipeline == pipeline + + def test_parse_create_view_invalid_json(self): + with pytest.raises(SqlSyntaxError, match="Invalid pipeline JSON"): + self.strategy._parse_sql("CREATE VIEW v ON c AS 'not json'") + + def test_parse_create_view_pipeline_not_array(self): + with pytest.raises(SqlSyntaxError, match="Pipeline must be a JSON array"): + self.strategy._parse_sql("CREATE VIEW v ON c AS '{\"$match\": {}}'") + + def test_parse_drop_view(self): + plan = self.strategy._parse_sql("DROP VIEW my_view") + assert isinstance(plan, ViewExecutionPlan) + assert plan.ddl_type == "drop_view" + assert plan.collection == "my_view" + assert plan.validate() + + def test_parse_unsupported_ddl(self): + with pytest.raises(SqlSyntaxError, match="Unsupported DDL"): + self.strategy._parse_sql("CREATE VIEW") + + def test_factory_selects_ddl_strategy(self): + ctx = ExecutionContext("CREATE VIEW v ON c AS '[]'") + strategy = ExecutionPlanFactory.get_strategy(ctx) + assert isinstance(strategy, ViewExecution) + + def test_factory_selects_ddl_for_drop(self): + ctx = ExecutionContext("DROP VIEW v") + strategy = ExecutionPlanFactory.get_strategy(ctx) + assert isinstance(strategy, ViewExecution) + + def test_plan_validation_missing_collection(self): + plan = ViewExecutionPlan(ddl_type="create_view", view_on="users", pipeline=[]) + assert not plan.validate() + + def test_plan_validation_missing_view_on(self): + plan = ViewExecutionPlan(collection="v", ddl_type="create_view", pipeline=[]) + assert not plan.validate() + + def test_plan_to_dict_create(self): + plan = ViewExecutionPlan(collection="v", ddl_type="create_view", view_on="users", pipeline=[{"$match": {}}]) + d = plan.to_dict() + assert d["ddl_type"] == "create_view" + assert d["collection"] == "v" + assert d["view_on"] == "users" + assert d["pipeline"] == [{"$match": {}}] + + def test_plan_to_dict_drop(self): + plan = ViewExecutionPlan(collection="v", ddl_type="drop_view") + d = plan.to_dict() + assert d["ddl_type"] == "drop_view" + assert "view_on" not in d + + +# --------------------------------------------------------------------------- +# Integration tests – require a running MongoDB instance +# --------------------------------------------------------------------------- + + +@pytest.mark.integration +class TestDDLIntegration: + """Integration tests for CREATE VIEW / DROP VIEW against MongoDB.""" + + VIEW_NAME = "test_ddl_view" + + @pytest.fixture(autouse=True) + def _cleanup_view(self, conn): + """Ensure the test view does not exist before and after each test.""" + db = conn.database + if self.VIEW_NAME in db.list_collection_names(): + db.drop_collection(self.VIEW_NAME) + yield + if self.VIEW_NAME in db.list_collection_names(): + db.drop_collection(self.VIEW_NAME) + + def test_create_view_and_query(self, conn): + cursor = conn.cursor() + + pipeline = json.dumps([{"$match": {"active": True}}]) + cursor.execute(f"CREATE VIEW {self.VIEW_NAME} ON users AS '{pipeline}'") + + # The view should now exist + view_names = conn.database.list_collection_names(filter={"type": "view"}) + assert self.VIEW_NAME in view_names + + # Query the view like a regular collection + cursor.execute(f"SELECT * FROM {self.VIEW_NAME}") + rows = cursor.fetchall() + assert len(rows) > 0 + + def test_create_view_with_projection_pipeline(self, conn): + cursor = conn.cursor() + + pipeline = json.dumps([{"$project": {"name": 1, "email": 1, "_id": 0}}]) + cursor.execute(f"CREATE VIEW {self.VIEW_NAME} ON users AS '{pipeline}'") + + cursor.execute(f"SELECT * FROM {self.VIEW_NAME}") + rows = cursor.fetchall() + assert len(rows) > 0 + + def test_drop_view(self, conn): + db = conn.database + # First create via MongoDB directly + db.command( + { + "create": self.VIEW_NAME, + "viewOn": "users", + "pipeline": [], + } + ) + assert self.VIEW_NAME in db.list_collection_names() + + cursor = conn.cursor() + cursor.execute(f"DROP VIEW {self.VIEW_NAME}") + + assert self.VIEW_NAME not in db.list_collection_names() + + def test_create_view_with_lookup(self, conn): + cursor = conn.cursor() + + pipeline = json.dumps( + [ + { + "$lookup": { + "from": "orders", + "localField": "_id", + "foreignField": "user_id", + "as": "user_orders", + } + } + ] + ) + cursor.execute(f"CREATE VIEW {self.VIEW_NAME} ON users AS '{pipeline}'") + + cursor.execute(f"SELECT * FROM {self.VIEW_NAME}") + rows = cursor.fetchall() + assert len(rows) > 0 + + def test_drop_nonexistent_view_succeeds_silently(self, conn): + """MongoDB drop on a non-existent namespace may succeed silently or raise.""" + cursor = conn.cursor() + # MongoDB 4.x+ returns ok:1 even when namespace doesn't exist. + # Just verify it doesn't crash unexpectedly. + cursor.execute("DROP VIEW nonexistent_view_xyz") + + def test_create_view_roundtrip(self, conn): + """CREATE VIEW -> query -> DROP VIEW -> confirm gone.""" + cursor = conn.cursor() + + pipeline = json.dumps([{"$match": {"active": True}}]) + cursor.execute(f"CREATE VIEW {self.VIEW_NAME} ON users AS '{pipeline}'") + + cursor.execute(f"SELECT * FROM {self.VIEW_NAME}") + rows = cursor.fetchall() + assert len(rows) > 0 + + cursor.execute(f"DROP VIEW {self.VIEW_NAME}") + assert self.VIEW_NAME not in conn.database.list_collection_names() From ac293f330a0f92c93d868f80f4a728da2742be5c Mon Sep 17 00:00:00 2001 From: Peng Ren Date: Sun, 19 Apr 2026 11:49:19 -0400 Subject: [PATCH 4/6] Update README --- HOW_IT_WORKS.md | 525 ------------------------------------------------ README.md | 34 ++++ 2 files changed, 34 insertions(+), 525 deletions(-) delete mode 100644 HOW_IT_WORKS.md diff --git a/HOW_IT_WORKS.md b/HOW_IT_WORKS.md deleted file mode 100644 index c46a350..0000000 --- a/HOW_IT_WORKS.md +++ /dev/null @@ -1,525 +0,0 @@ -# PyMongoSQL Architecture & Class Diagram - -## Overview - -PyMongoSQL is a Python library that provides a SQL-to-MongoDB translation layer with DB API 2.0 compliance and SQLAlchemy integration. The architecture consists of three main layers: - -1. **Database API Layer** - DB API 2.0 compliant interface (Connection, Cursor, ResultSet) -2. **SQL Processing Layer** - ANTLR4-based PartiQL parser with MongoDB execution builders -3. **Integration Layer** - SQLAlchemy dialect and Superset support - ---- - -## Class Hierarchy Diagram - -```mermaid -classDiagram - %% ==================== DATABASE API LAYER ==================== - - class Connection { - -host: str - -port: int - -mongo_client: MongoClient - -mode: str - +cursor() Cursor - +close() - +commit() - +rollback() - +get_database() Database - } - - class BaseCursor { - <> - -connection: Connection - -mode: str - +execute(operation, parameters) ResultSet - +fetchone() Sequence - +fetchall() List[Sequence] - +description: List - } - - class Cursor { - -result_set: ResultSet - -current_execution_plan: ExecutionPlan - -is_closed: bool - +execute(operation, parameters)* ResultSet - +executemany(operation, seq_of_params) - +fetchone() Sequence - +fetchall() List[Sequence] - +fetchmany(size) List[Sequence] - +close() - +__iter__() - +__next__() Sequence - } - - class DictCursor { - -result_set_class: DictResultSet - +fetchone() Dict - +fetchall() List[Dict] - } - - class CursorIterator { - -arraysize: int - +__iter__() - +__next__() - } - - class ResultSet { - -command_result: Dict - -execution_plan: QueryExecutionPlan - -raw_results: List - -cached_results: List - -column_names: List[str] - -description: List - +description - +fetch(rows) Sequence - +fetchone() Sequence - +fetchall() List[Sequence] - +fetchmany(size) List[Sequence] - +close() - +__iter__() - +__next__() - } - - class DictResultSet { - -column_names: List[str] - +fetch(rows) List[Dict] - +fetchone() Dict - +fetchall() List[Dict] - } - - %% ==================== SQL PARSING LAYER ==================== - - class SQLParser { - -original_sql: str - -preprocessed_sql: str - -ast: Any - -visitor: MongoSQLParserVisitor - +parse() ExecutionPlan - +get_prepared_statement() str - } - - class ExecutionPlanFactory { - +create_from_parsed() ExecutionPlan - } - - class ExecutionPlan { - <> - -collection: str - +to_dict() Dict - +validate() bool - +copy() ExecutionPlan - } - - class QueryExecutionPlan { - -filter_stage: Dict - -projection_stage: Dict - -sort_stage: List - -limit_stage: int - -skip_stage: int - +to_dict() Dict - +validate() bool - } - - class InsertExecutionPlan { - -insert_documents: List[Dict] - -parameter_style: str - -parameter_count: int - +to_dict() Dict - +validate() bool - } - - class UpdateExecutionPlan { - -filter_stage: Dict - -update_stage: Dict - +to_dict() Dict - +validate() bool - } - - class DeleteExecutionPlan { - -filter_stage: Dict - +to_dict() Dict - +validate() bool - } - - %% ==================== SQL HANDLER LAYER ==================== - - class MongoSQLParserVisitor { - <> - +visitQuery() QueryExecutionPlan - +visitInsert() InsertExecutionPlan - +visitUpdate() UpdateExecutionPlan - +visitDelete() DeleteExecutionPlan - +visitWhere() Dict - +visitExpression() Any - } - - class QueryHandler { - <> - +create_execution_plan() QueryExecutionPlan - +build_filter() Dict - +build_projection() Dict - } - - class InsertHandler { - <> - +create_execution_plan() InsertExecutionPlan - +build_documents() List[Dict] - +detect_parameter_style() str - } - - class UpdateHandler { - <> - +create_execution_plan() UpdateExecutionPlan - +build_update_doc() Dict - } - - class DeleteHandler { - <> - +create_execution_plan() DeleteExecutionPlan - +build_filter() Dict - } - - class ContextUtilsMixin { - <> - +get_context_text() str - +get_context_type_name() str - +has_children() bool - +normalize_field_path() str - } - - %% ==================== EXECUTION LAYER ==================== - - class ExecutionContext { - -query: str - -execution_mode: str - -parameters: Union[Sequence, Dict] - } - - class ExecutionStrategy { - <> - +execute_plan: ExecutionPlan - +execute() Dict - } - - class QueryExecutionStrategy { - +execute() Dict - } - - class InsertExecutionStrategy { - +execute() Dict - } - - class UpdateExecutionStrategy { - +execute() Dict - } - - class DeleteExecutionStrategy { - +execute() Dict - } - - class ExecutionPlanFactory { - +create_from_operation() ExecutionPlan - +create_query_plan() QueryExecutionPlan - +create_insert_plan() InsertExecutionPlan - } - - %% ==================== SQLALCHEMY INTEGRATION ==================== - - class PyMongoSQLDialect { - -execution_ctx_cls: ExecutionContext - +initialize() Connection - +create_connect_args() Dict - +compiler_class: TypeCompiler - +type_compiler_class: TypeCompiler - } - - class PyMongoSQLIdentifierPreparer { - <> - -reserved_words: Set[str] - +quote_identifier() str - } - - class PyMongoSQLTypeCompiler { - <> - +process_result_value() Any - } - - class PyMongoSQLStatementCompiler { - <> - +visit_select() str - +visit_insert() str - +visit_update() str - +visit_delete() str - } - - %% ==================== ERROR HANDLING ==================== - - class Error { - <> - } - - class DatabaseError { - <> - } - - class OperationalError { - <> - } - - class ProgrammingError { - <> - } - - class SqlSyntaxError { - <> - } - - class NotSupportedError { - <> - } - - %% ==================== HELPER CLASSES ==================== - - class ConnectionHelper { - +parse_connection_string() Dict - +extract_mode() str - +get_database_config() Dict - } - - class SQLHelper { - +prepare_statement() str - +detect_parameter_style() str - +bind_parameters() str - } - - %% ==================== RELATIONSHIPS ==================== - - %% Database API Layer - Connection --> BaseCursor: creates - Cursor --|> BaseCursor - DictCursor --|> BaseCursor - CursorIterator <|-- Cursor - CursorIterator <|-- ResultSet - Cursor --> ResultSet: manages - Cursor --> ExecutionContext: creates - Cursor --> ExecutionPlanFactory: uses - ResultSet --> QueryExecutionPlan: uses - - %% SQL Parsing Layer - SQLParser --> ExecutionPlanFactory: uses - SQLParser --> MongoSQLParserVisitor: uses - ExecutionPlan <|-- QueryExecutionPlan - ExecutionPlan <|-- InsertExecutionPlan - ExecutionPlan <|-- UpdateExecutionPlan - ExecutionPlan <|-- DeleteExecutionPlan - - %% SQL Handler Layer - MongoSQLParserVisitor --> QueryHandler: delegates to - MongoSQLParserVisitor --> InsertHandler: delegates to - MongoSQLParserVisitor --> UpdateHandler: delegates to - MongoSQLParserVisitor --> DeleteHandler: delegates to - ContextUtilsMixin <|-- MongoSQLParserVisitor - ContextUtilsMixin <|-- QueryHandler - - %% Execution Layer - ExecutionStrategy <|-- QueryExecutionStrategy - ExecutionStrategy <|-- InsertExecutionStrategy - ExecutionStrategy <|-- UpdateExecutionStrategy - ExecutionStrategy <|-- DeleteExecutionStrategy - ExecutionContext --> ExecutionStrategy: drives - ExecutionPlanFactory --> ExecutionPlan: produces - - %% SQLAlchemy Integration - PyMongoSQLDialect --> Connection: creates - PyMongoSQLDialect --> PyMongoSQLIdentifierPreparer: uses - PyMongoSQLDialect --> PyMongoSQLTypeCompiler: uses - PyMongoSQLDialect --> PyMongoSQLStatementCompiler: uses - PyMongoSQLStatementCompiler --> SQLParser: uses - - %% Error Handling - Error <|-- DatabaseError - Error <|-- OperationalError - Error <|-- ProgrammingError - Error <|-- SqlSyntaxError - Error <|-- NotSupportedError - - %% Helpers - Connection --> ConnectionHelper: uses - Cursor --> SQLHelper: uses -``` - ---- - -## Layer Details - -### 1. Database API Layer (DB API 2.0 Compliant) - -**Purpose**: Provides a standard Python database interface similar to PyMySQL, psycopg2, etc. - -| Class | Responsibility | Key Methods | -|-------|----------------|------------| -| `Connection` | Manages MongoDB connection; creates cursors | `cursor()`, `close()`, `commit()`, `rollback()` | -| `BaseCursor` | Abstract base for cursor implementations | `execute()`, `fetchone()`, `fetchall()` | -| `Cursor` | Standard cursor with sequence results | `fetchone()`, `fetchall()`, `executemany()` | -| `DictCursor` | Cursor returning dictionaries instead of tuples | `fetchone()` → `Dict` | -| `ResultSet` | Manages query result caching and fetching | `fetch()`, `fetchone()`, `fetchall()` | -| `DictResultSet` | ResultSet variant for dictionary-based results | Inherits from `ResultSet` | - -### 2. SQL Processing Layer (ANTLR4 PartiQL Parser) - -**Purpose**: Parses SQL/PartiQL statements and builds execution plans for MongoDB. - -| Class | Responsibility | Key Attributes | -|-------|----------------|-----------------| -| `SQLParser` | Main parser entry point; orchestrates ANTLR parsing | `_ast`, `_visitor`, `_preprocessed_sql` | -| `ExecutionPlanFactory` | Factory pattern for creating execution plans | Creates typed plans from parsed AST | -| `ExecutionPlan` | Abstract base for all execution plans | `collection`, `validate()`, `to_dict()` | -| `QueryExecutionPlan` | Execution plan for SELECT queries | `filter_stage`, `projection_stage`, `sort_stage` | -| `InsertExecutionPlan` | Execution plan for INSERT operations | `insert_documents`, `parameter_style` | -| `UpdateExecutionPlan` | Execution plan for UPDATE operations | `filter_stage`, `update_stage` | -| `DeleteExecutionPlan` | Execution plan for DELETE operations | `filter_stage` | - -### 3. SQL Handler Layer (Visitor Pattern) - -**Purpose**: Translates parsed AST nodes into MongoDB operations using visitor pattern. - -| Class | Responsibility | Key Methods | -|-------|----------------|------------| -| `MongoSQLParserVisitor` | Main visitor; delegates to specific handlers | `visitQuery()`, `visitInsert()`, `visitUpdate()`, `visitDelete()` | -| `QueryHandler` | Handles SELECT statement parsing | `build_filter()`, `build_projection()` | -| `InsertHandler` | Handles INSERT statement parsing | `build_documents()`, `detect_parameter_style()` | -| `UpdateHandler` | Handles UPDATE statement parsing | `build_update_doc()` | -| `DeleteHandler` | Handles DELETE statement parsing | `build_filter()` | -| `ContextUtilsMixin` | Shared utility methods for AST traversal | `get_context_text()`, `normalize_field_path()` | - -### 4. Execution Layer - -**Purpose**: Executes parsed plans against MongoDB. - -| Class | Responsibility | Key Methods | -|-------|----------------|------------| -| `ExecutionContext` | Holds query execution metadata | `query`, `execution_mode`, `parameters` | -| `ExecutionStrategy` | Abstract strategy for query execution | `execute()` | -| `QueryExecutionStrategy` | Executes SELECT queries | Returns result set | -| `InsertExecutionStrategy` | Executes INSERT operations | Returns insert result | -| `UpdateExecutionStrategy` | Executes UPDATE operations | Returns update result | -| `DeleteExecutionStrategy` | Executes DELETE operations | Returns delete result | - -### 5. SQLAlchemy Integration Layer - -**Purpose**: Provides SQLAlchemy dialect for ORM and SQLAlchemy Core support. - -| Class | Responsibility | Key Role | -|-------|----------------|----------| -| `PyMongoSQLDialect` | Main dialect implementation | Inherits from `sqlalchemy.engine.default.DefaultDialect` | -| `PyMongoSQLIdentifierPreparer` | Handles MongoDB identifier quoting | Reserved word checking | -| `PyMongoSQLTypeCompiler` | Type mapping SQL↔MongoDB | Converts between SQL and BSON types | -| `PyMongoSQLStatementCompiler` | Compiles SQLAlchemy AST to SQL | `visit_select()`, `visit_insert()`, etc. | - -### 6. Error Handling - -**Purpose**: Provides DB API 2.0 compliant exception hierarchy. - -``` -Error (base) -├── DatabaseError -├── OperationalError -├── ProgrammingError -├── SqlSyntaxError -└── NotSupportedError -``` - ---- - -## Data Flow Diagrams - -### Query Execution Flow - -``` -User Code - ↓ -Cursor.execute(sql_string, parameters) - ↓ -ExecutionContext (holds query + params) - ↓ -SQLParser.parse() - ├─→ ANTLR lexer/parser - ├─→ MongoSQLParserVisitor - └─→ Handlers (Query/Insert/Update/Delete) - ↓ -ExecutionPlan (QueryExecutionPlan, InsertExecutionPlan, etc.) - ↓ -ExecutionStrategy (QueryExecutionStrategy, InsertExecutionStrategy, etc.) - ↓ -MongoDB Collection Operations - ├─→ collection.find() [SELECT] - ├─→ collection.insert_many() [INSERT] - ├─→ collection.update_many() [UPDATE] - └─→ collection.delete_many() [DELETE] - ↓ -MongoDB Command Result - ↓ -ResultSet (caches and iterates results) - ↓ -Cursor.fetchone()/fetchall()/fetchmany() - ↓ -User receives Sequence or Dict -``` - -### SQLAlchemy Integration Flow - -``` -SQLAlchemy Core/ORM Code - ↓ -PyMongoSQLDialect - ├─→ PyMongoSQLStatementCompiler.visit_select() - ├─→ PyMongoSQLStatementCompiler.visit_insert() - ├─→ PyMongoSQLStatementCompiler.visit_update() - └─→ PyMongoSQLStatementCompiler.visit_delete() - ↓ -Generated SQL String - ↓ -Cursor.execute(sql_string) - ↓ -SQLParser + Handlers + ExecutionStrategies - ↓ -MongoDB Results - ↓ -ResultSet - ↓ -SQLAlchemy ORM/Core Result Proxy - ↓ -User receives ORM objects or rows -``` - ---- - -## Superset Integration - -PyMongoSQL provides specialized support for Apache Superset with a **two-stage execution strategy**: - -### Key Points - -- **Connection Mode**: Use `mode='superset'` for complex SQL support - ```python - conn = Connection(uri="mongodb://localhost:27017/mydb?mode=superset") - ``` - -- **Two-Stage Execution**: - 1. **Stage 1**: Execute subquery on MongoDB (translate SQL to aggregation pipeline) - 2. **Stage 2**: Cache results in temporary SQLite3 table, execute complex SQL (GROUP BY, HAVING, window functions) - -- **Query Detection** (`SubqueryDetector`): - - Detects wrapped subqueries: `SELECT ... FROM (SELECT ... FROM collection) AS alias` - - Falls back to direct MongoDB execution for simple queries - -- **Core Classes**: - | Class | Purpose | - |-------|---------| - | `SupersetExecution` | Two-stage execution strategy | - | `SubqueryDetector` | Analyzes query structure | - | `QueryDBSQLite` | In-memory SQLite3 backend for intermediate results | - -- **Benefits**: Native MongoDB support in Superset dashboards with full SQL capability -- **Limitations**: Single collection queries, session-scoped caching, performance depends on result set size diff --git a/README.md b/README.md index a28c883..cc5e1ec 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ pip install -e . - [INSERT Statements](#insert-statements) - [UPDATE Statements](#update-statements) - [DELETE Statements](#delete-statements) + - [View Management](#view-management) - [Transaction Support](#transaction-support) - [SQL to MongoDB Mapping](#sql-to-mongodb-mapping) - [Apache Superset Integration](#apache-superset-integration) @@ -510,6 +511,37 @@ cursor.execute("DELETE FROM Music WHERE available = false") print(f"Deleted {cursor.rowcount} documents") ``` +### View Management + +PyMongoSQL supports creating and dropping MongoDB views using SQL syntax. + +**CREATE VIEW** + +```python +import json + +# Create a view with a filter pipeline +pipeline = json.dumps([{"$match": {"active": True}}]) +cursor.execute(f"CREATE VIEW active_users ON users AS '{pipeline}'") + +# Create a view with a $lookup (join) pipeline +pipeline = json.dumps([ + {"$lookup": {"from": "orders", "localField": "_id", "foreignField": "user_id", "as": "user_orders"}} +]) +cursor.execute(f"CREATE VIEW users_with_orders ON users AS '{pipeline}'") + +# Query the view like any collection +cursor.execute("SELECT * FROM active_users") +``` + +**DROP VIEW** + +```python +cursor.execute("DROP VIEW active_users") +``` + +**Note:** The pipeline must be a valid JSON array string enclosed in single quotes. `CREATE VIEW` maps to `db.command({"create": view_name, "viewOn": collection, "pipeline": [...]})` and `DROP VIEW` maps to `db.command({"drop": view_name})`. + ### Transaction Support PyMongoSQL supports DB API 2.0 transactions for ACID-compliant database operations. Use the `begin()`, `commit()`, and `rollback()` methods to manage transactions: @@ -554,6 +586,8 @@ The table below shows how PyMongoSQL translates SQL operations into MongoDB comm | `INSERT INTO col ...` | `{insert: col, documents: [...]}` | `db.command("insert", ...)` | | `UPDATE col SET ... WHERE ...` | `{update: col, updates: [{q: filter, u: {$set: {...}}, multi: true}]}` | `db.command("update", ...)` | | `DELETE FROM col WHERE ...` | `{delete: col, deletes: [{q: filter, limit: 0}]}` | `db.command("delete", ...)` | +| `CREATE VIEW v ON col AS '[...]'` | `{create: v, viewOn: col, pipeline: [...]}` | `db.command("create", ...)` | +| `DROP VIEW v` | `{drop: v}` | `db.command("drop", ...)` | ### SQL Clauses to MongoDB Query Components From d36b208166b038fb3444aa7fe4bdf467b1d99a0d Mon Sep 17 00:00:00 2001 From: Peng Ren Date: Sun, 19 Apr 2026 11:55:55 -0400 Subject: [PATCH 5/6] Add markers for unit tests --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 1c34df9..d083fac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,6 +93,7 @@ python_classes = ["Test*"] python_functions = ["test_*"] markers = [ "transactional: marks tests that require MongoDB transaction support (requires replica set or sharded cluster)", + "integration: marks tests that require a running MongoDB instance", ] [tool.coverage.run] From d4c2b55889356224641b953f4e96071924168da9 Mon Sep 17 00:00:00 2001 From: Peng Ren Date: Sun, 19 Apr 2026 12:04:14 -0400 Subject: [PATCH 6/6] Regenerate parsers from partiql.g4 files --- pymongosql/sql/partiql/PartiQLLexer.py | 4 +- pymongosql/sql/partiql/PartiQLParser.py | 3611 +++++++++-------- .../sql/partiql/PartiQLParserListener.py | 2 +- .../sql/partiql/PartiQLParserVisitor.py | 2 +- 4 files changed, 1828 insertions(+), 1791 deletions(-) diff --git a/pymongosql/sql/partiql/PartiQLLexer.py b/pymongosql/sql/partiql/PartiQLLexer.py index e8c9e3c..5c71e8a 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.1 +# Generated from PartiQLLexer.g4 by ANTLR 4.13.2 from antlr4 import * from io import StringIO import sys @@ -1682,7 +1682,7 @@ class PartiQLLexer(Lexer): def __init__(self, input=None, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/pymongosql/sql/partiql/PartiQLParser.py b/pymongosql/sql/partiql/PartiQLParser.py index 73369e8..eb16e4f 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.1 +# Generated from PartiQLParser.g4 by ANTLR 4.13.2 # encoding: utf-8 from antlr4 import * from io import StringIO @@ -10,7 +10,7 @@ def serializedATN(): return [ - 4,1,311,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, + 4,1,311,1837,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, @@ -41,721 +41,726 @@ def serializedATN(): 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, + 9,15,1,15,1,15,1,15,1,15,1,15,1,15,1,15,1,15,1,15,1,15,3,15,400, + 8,15,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16, + 3,16,414,8,16,1,17,1,17,1,17,5,17,419,8,17,10,17,12,17,422,9,17, + 1,18,1,18,1,18,5,18,427,8,18,10,18,12,18,430,9,18,1,19,1,19,3,19, + 434,8,19,1,19,1,19,1,20,1,20,1,20,3,20,441,8,20,1,21,1,21,4,21,445, + 8,21,11,21,12,21,446,1,21,3,21,450,8,21,1,21,3,21,453,8,21,1,21, + 1,21,3,21,457,8,21,1,21,4,21,460,8,21,11,21,12,21,461,1,21,3,21, + 465,8,21,1,21,1,21,1,21,3,21,470,8,21,1,22,1,22,1,22,1,22,1,22,1, + 22,3,22,478,8,22,1,23,1,23,5,23,482,8,23,10,23,12,23,485,9,23,1, + 24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,3,24,497,8,24,1, + 25,1,25,1,25,1,25,3,25,503,8,25,1,25,1,25,1,26,1,26,1,26,1,26,3, + 26,511,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,525,8,28,1,28,3,28,528,8,28,1,28,3,28,531,8,28,1,29, + 1,29,1,29,1,29,3,29,537,8,29,1,29,1,29,3,29,541,8,29,1,29,1,29,1, + 29,1,29,3,29,547,8,29,1,29,1,29,3,29,551,8,29,3,29,553,8,29,1,30, + 1,30,1,30,1,30,5,30,559,8,30,10,30,12,30,562,9,30,1,30,1,30,1,31, + 1,31,1,31,3,31,569,8,31,1,31,1,31,1,32,1,32,1,32,1,32,1,32,1,32, + 1,32,3,32,580,8,32,1,32,3,32,583,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,596,8,34,10,34,12,34,599,9,34,1, + 34,1,34,1,34,1,34,1,34,3,34,606,8,34,1,35,1,35,1,36,1,36,1,36,1, + 36,1,36,1,36,1,36,1,36,3,36,618,8,36,1,37,1,37,1,37,3,37,623,8,37, + 1,38,1,38,1,38,3,38,628,8,38,1,39,1,39,1,39,1,40,1,40,1,40,1,40, + 5,40,637,8,40,10,40,12,40,640,9,40,1,41,1,41,1,41,1,41,1,42,1,42, + 1,42,3,42,649,8,42,1,42,3,42,652,8,42,1,43,1,43,1,43,1,43,5,43,658, + 8,43,10,43,12,43,661,9,43,1,44,1,44,1,44,1,44,1,44,1,44,3,44,669, + 8,44,1,45,1,45,1,45,3,45,674,8,45,1,45,3,45,677,8,45,1,45,3,45,680, + 8,45,1,45,1,45,1,45,1,45,3,45,686,8,45,1,46,1,46,1,46,1,47,1,47, + 3,47,693,8,47,1,47,1,47,1,47,3,47,698,8,47,1,47,1,47,1,47,3,47,703, + 8,47,1,47,1,47,1,47,1,47,1,47,1,47,1,47,3,47,712,8,47,1,48,1,48, + 1,48,5,48,717,8,48,10,48,12,48,720,9,48,1,49,1,49,3,49,724,8,49, + 1,49,3,49,727,8,49,1,50,1,50,1,51,1,51,1,51,1,51,5,51,735,8,51,10, + 51,12,51,738,9,51,1,52,1,52,1,52,1,52,1,53,1,53,1,53,1,53,1,53,5, + 53,749,8,53,10,53,12,53,752,9,53,1,54,1,54,3,54,756,8,54,1,54,1, + 54,3,54,760,8,54,1,55,1,55,3,55,764,8,55,1,55,1,55,1,55,1,55,5,55, + 770,8,55,10,55,12,55,773,9,55,1,55,3,55,776,8,55,1,56,1,56,1,56, + 1,56,1,57,1,57,1,57,3,57,785,8,57,1,58,1,58,1,58,3,58,790,8,58,1, + 58,3,58,793,8,58,1,58,1,58,1,59,1,59,1,59,1,59,1,59,5,59,802,8,59, + 10,59,12,59,805,9,59,1,60,1,60,1,60,1,60,1,60,5,60,812,8,60,10,60, + 12,60,815,9,60,1,61,1,61,1,61,1,62,1,62,1,62,1,62,5,62,824,8,62, + 10,62,12,62,827,9,62,1,63,1,63,4,63,831,8,63,11,63,12,63,832,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, + 848,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,863,8,69,1,69,1,69,1,70,3,70,868,8,70,1,70,1,70,1, + 70,5,70,873,8,70,10,70,12,70,876,9,70,1,71,3,71,879,8,71,1,71,3, + 71,882,8,71,1,71,5,71,885,8,71,10,71,12,71,888,9,71,1,72,1,72,1, + 72,3,72,893,8,72,1,73,1,73,1,73,1,73,3,73,899,8,73,1,73,1,73,1,73, + 3,73,904,8,73,3,73,906,8,73,1,74,1,74,1,74,1,75,1,75,1,76,1,76,3, + 76,915,8,76,1,76,1,76,3,76,919,8,76,1,76,3,76,922,8,76,1,76,1,76, + 1,77,1,77,3,77,928,8,77,1,77,1,77,3,77,932,8,77,3,77,934,8,77,1, + 78,1,78,3,78,938,8,78,1,78,3,78,941,8,78,1,78,4,78,944,8,78,11,78, + 12,78,945,1,78,3,78,949,8,78,1,78,1,78,3,78,953,8,78,1,78,1,78,3, + 78,957,8,78,1,78,3,78,960,8,78,1,78,4,78,963,8,78,11,78,12,78,964, + 1,78,3,78,968,8,78,1,78,1,78,3,78,972,8,78,3,78,974,8,78,1,79,1, + 79,1,79,1,79,1,79,3,79,981,8,79,1,79,3,79,984,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,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,80,1,80,1,80,1,80,1,80,3,80,1020,8,80,1,81,1,81,3,81,1024,8,81, + 1,81,1,81,3,81,1028,8,81,1,81,3,81,1031,8,81,1,81,1,81,1,82,1,82, + 1,82,1,82,1,82,1,82,5,82,1041,8,82,10,82,12,82,1044,9,82,1,83,1, + 83,1,83,1,83,1,83,1,83,5,83,1052,8,83,10,83,12,83,1055,9,83,1,84, + 1,84,1,84,3,84,1060,8,84,1,85,1,85,1,85,1,85,1,85,1,85,3,85,1068, + 8,85,1,86,1,86,1,86,1,86,1,86,1,86,3,86,1076,8,86,1,86,1,86,3,86, + 1080,8,86,3,86,1082,8,86,1,87,1,87,1,87,1,87,1,87,1,87,3,87,1090, + 8,87,1,87,1,87,3,87,1094,8,87,1,87,1,87,1,87,1,87,1,87,1,87,1,87, + 1,87,3,87,1104,8,87,1,87,1,87,1,87,1,87,5,87,1110,8,87,10,87,12, + 87,1113,9,87,1,88,1,88,3,88,1117,8,88,1,89,1,89,1,89,1,89,1,89,3, + 89,1124,8,89,1,89,3,89,1127,8,89,1,89,3,89,1130,8,89,1,89,1,89,3, + 89,1134,8,89,1,89,3,89,1137,8,89,1,89,3,89,1140,8,89,3,89,1142,8, + 89,1,90,1,90,1,90,3,90,1147,8,90,1,90,3,90,1150,8,90,1,90,3,90,1153, + 8,90,1,91,1,91,1,91,1,91,1,91,3,91,1160,8,91,1,92,1,92,1,92,1,93, + 1,93,1,93,3,93,1168,8,93,1,93,1,93,3,93,1172,8,93,1,93,1,93,3,93, + 1176,8,93,1,93,3,93,1179,8,93,1,94,1,94,1,95,1,95,1,95,1,95,1,95, + 3,95,1188,8,95,1,95,1,95,3,95,1192,8,95,1,95,1,95,1,95,3,95,1197, + 8,95,1,95,1,95,3,95,1201,8,95,1,95,1,95,1,95,3,95,1206,8,95,1,95, + 1,95,3,95,1210,8,95,1,95,5,95,1213,8,95,10,95,12,95,1216,9,95,1, + 96,1,96,3,96,1220,8,96,1,96,1,96,3,96,1224,8,96,1,96,3,96,1227,8, + 96,1,96,3,96,1230,8,96,1,96,3,96,1233,8,96,1,96,3,96,1236,8,96,1, + 96,3,96,1239,8,96,1,96,3,96,1242,8,96,1,96,3,96,1245,8,96,1,97,1, + 97,1,97,1,97,1,97,1,97,5,97,1253,8,97,10,97,12,97,1256,9,97,1,98, + 1,98,1,98,1,98,1,98,1,98,5,98,1264,8,98,10,98,12,98,1267,9,98,1, + 99,1,99,1,99,3,99,1272,8,99,1,100,1,100,1,100,1,100,1,100,1,100, + 1,100,1,100,1,100,3,100,1283,8,100,1,100,1,100,1,100,3,100,1288, + 8,100,1,100,1,100,1,100,1,100,1,100,1,100,1,100,3,100,1297,8,100, + 1,100,1,100,1,100,1,100,3,100,1303,8,100,1,100,1,100,1,100,1,100, + 3,100,1309,8,100,1,100,1,100,3,100,1313,8,100,1,100,1,100,1,100, + 1,100,1,100,5,100,1320,8,100,10,100,12,100,1323,9,100,1,101,1,101, + 1,101,1,101,1,101,1,101,5,101,1331,8,101,10,101,12,101,1334,9,101, + 1,102,1,102,1,102,1,102,1,102,1,102,5,102,1342,8,102,10,102,12,102, + 1345,9,102,1,103,1,103,1,103,1,103,1,103,1,103,5,103,1353,8,103, + 10,103,12,103,1356,9,103,1,104,1,104,1,104,3,104,1361,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,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, - 144,146,148,150,152,154,156,158,160,162,164,166,168,170,172,174, - 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,278,0,21,1,0,304,305,2,0,4,4,248,248,1,0,249,250,2,0, - 4,4,68,68,2,0,11,11,63,63,2,0,91,91,124,124,2,0,4,4,8,8,2,0,272, - 272,278,278,2,0,282,285,287,288,2,0,280,280,286,286,1,0,272,273, - 2,0,274,275,278,278,1,0,267,268,7,0,8,8,15,15,44,44,76,76,132,133, - 190,190,197,197,1,0,231,232,1,0,87,88,12,0,19,19,28,29,44,44,53, - 54,83,83,130,130,146,146,174,174,188,188,196,196,208,208,214,214, - 9,0,8,8,26,27,53,53,114,115,142,142,171,171,189,189,237,237,252, - 269,3,0,26,27,92,92,221,221,2,0,56,57,145,145,1,0,202,203,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,84,0,0,281,282,5,295,0,0,282,287,3,4,2,0,283,284, - 5,271,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,296,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, - 298,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,298,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,298,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,298,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,304,0,0,318,319,5,304,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,81,0,0,334,343,3,188,94,0,335,340,3,188,94,0,336,337,5, - 271,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,300,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,199,0,0,369,374,3,18,9,0,370,371,5,295,0,0,371,372,3,34,17, - 0,372,373,5,296,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,243,0,0,378,379,5, - 148,0,0,379,380,3,12,6,0,380,381,5,295,0,0,381,386,3,46,23,0,382, - 383,5,271,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,296,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,71,0,0,394,395,5,199,0,0,395,403,3,18, - 9,0,396,397,5,71,0,0,397,398,5,243,0,0,398,399,3,12,6,0,399,400, - 5,148,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,271,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,141,0,0,427,430, - 5,142,0,0,428,430,5,142,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,291,0,0,476,477,3,276,138,0, - 477,478,5,292,0,0,478,486,1,0,0,0,479,480,5,291,0,0,480,481,3,12, - 6,0,481,482,5,292,0,0,482,486,1,0,0,0,483,484,5,300,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,174,0,0,488,489,5,118,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,215,0,0,496,497,5,118,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,242, - 0,0,504,505,3,46,23,0,505,55,1,0,0,0,506,507,5,113,0,0,507,508,5, - 118,0,0,508,509,3,46,23,0,509,510,5,219,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,113,0,0,522,523,5,118,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,113,0,0,532,533,5,118,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,295,0,0,544,549,3,24,12,0,545,546,5, - 271,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,296,0,0,553,61,1,0,0,0,554,555,5,148,0,0,555,557,5,245,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,113,0,0,562,563,5,118,0,0, - 563,564,3,46,23,0,564,565,5,219,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,148,0,0,574,575,5,245,0,0,575,576,5,226,0,0,576, - 577,3,188,94,0,577,578,5,246,0,0,578,579,5,251,0,0,579,67,1,0,0, - 0,580,581,5,295,0,0,581,586,3,12,6,0,582,583,5,271,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,296,0,0,590,595, - 1,0,0,0,591,592,5,148,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,246,0,0,599,607,5,251,0,0,600,601,5,246,0,0, - 601,602,5,174,0,0,602,607,3,74,37,0,603,604,5,246,0,0,604,605,5, - 213,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,80,0,0,609,610,5,226,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,80,0,0,614,615,5,226,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,213,0,0,619,620,3,178,89,0, - 620,79,1,0,0,0,621,622,5,186,0,0,622,627,3,82,41,0,623,624,5,271, - 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,284,0,0,632,633,3,188,94,0,633,83,1,0,0,0,634,635, - 5,62,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,247,0,0,643,648,3,88,44,0,644, - 645,5,271,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,278,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,96,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,96,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,226,0,0,677,678,3,188,94,0, - 678,93,1,0,0,0,679,681,5,183,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,278,0,0,684,686,5, - 183,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,183,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,219,0,0,694, - 701,3,188,94,0,695,696,5,238,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,271,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, - 244,0,0,720,725,3,104,52,0,721,722,5,271,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,153,0,0,733,734,5, - 20,0,0,734,739,3,108,54,0,735,736,5,271,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,143,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,103,0,0,751,753,5,159,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,271, - 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,103,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,233,0,0,776,778,5,295, - 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,296,0,0,784,117,1,0,0,0,785,786,5,234,0,0,786, - 787,5,20,0,0,787,792,3,188,94,0,788,789,5,271,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,153,0,0,796,797,5, - 20,0,0,797,802,3,108,54,0,798,799,5,271,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,104,0,0,806,807,3,192,96,0, - 807,123,1,0,0,0,808,809,5,79,0,0,809,814,3,126,63,0,810,811,5,271, - 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,300,0,0,824,837, - 3,12,6,0,825,826,5,291,0,0,826,827,5,301,0,0,827,837,5,292,0,0,828, - 829,5,291,0,0,829,830,5,302,0,0,830,837,5,292,0,0,831,832,5,291, - 0,0,832,833,5,278,0,0,833,837,5,292,0,0,834,835,5,300,0,0,835,837, - 5,278,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,96,0,0,839,840, - 3,174,87,0,840,131,1,0,0,0,841,842,5,226,0,0,842,843,3,192,96,0, - 843,133,1,0,0,0,844,845,5,241,0,0,845,846,3,192,96,0,846,135,1,0, - 0,0,847,848,5,240,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,271,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,187,0,0,885, - 887,5,8,0,0,886,888,5,302,0,0,887,886,1,0,0,0,887,888,1,0,0,0,888, - 895,1,0,0,0,889,890,5,187,0,0,890,892,5,302,0,0,891,893,5,103,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,284,0,0,898,149,1,0,0,0,899,900,5,304,0,0,900,151,1, - 0,0,0,901,903,5,295,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,297,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,296,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,295,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,296,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,291,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,292,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,293,0, - 0,966,967,5,302,0,0,967,969,5,271,0,0,968,970,5,302,0,0,969,968, - 1,0,0,0,969,970,1,0,0,0,970,971,1,0,0,0,971,973,5,294,0,0,972,964, - 1,0,0,0,972,965,1,0,0,0,973,159,1,0,0,0,974,975,5,273,0,0,975,976, - 3,162,81,0,976,977,5,273,0,0,977,978,5,288,0,0,978,1009,1,0,0,0, - 979,980,5,277,0,0,980,981,3,162,81,0,981,982,5,277,0,0,982,1009, - 1,0,0,0,983,984,5,287,0,0,984,985,5,273,0,0,985,986,3,162,81,0,986, - 987,5,273,0,0,987,1009,1,0,0,0,988,989,5,277,0,0,989,990,3,162,81, - 0,990,991,5,277,0,0,991,992,5,288,0,0,992,1009,1,0,0,0,993,994,5, - 287,0,0,994,995,5,277,0,0,995,996,3,162,81,0,996,997,5,277,0,0,997, - 1009,1,0,0,0,998,999,5,287,0,0,999,1000,5,273,0,0,1000,1001,3,162, - 81,0,1001,1002,5,273,0,0,1002,1003,5,288,0,0,1003,1009,1,0,0,0,1004, - 1005,5,273,0,0,1005,1006,3,162,81,0,1006,1007,5,273,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,291,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,297,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,292,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,279,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,280,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,281, - 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,275,0,0,1052,1053,5,295,0,0,1053,1054,3,164,82,0,1054,1055,5,296, - 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,277,0,0,1059,1060,5,277,0,0, - 1060,1071,5,288,0,0,1061,1062,5,287,0,0,1062,1071,5,277,0,0,1063, - 1065,5,287,0,0,1064,1063,1,0,0,0,1064,1065,1,0,0,0,1065,1066,1,0, - 0,0,1066,1068,5,273,0,0,1067,1069,5,288,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,295,0,0,1075,1076,3,174, - 87,0,1076,1077,5,296,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,121,0,0,1086,1099,3,182,91,0,1087,1088, - 10,4,0,0,1088,1089,5,271,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,121,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,239,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,295,0,0,1145, - 1146,3,174,87,0,1146,1147,5,296,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,148,0,0,1151, - 1152,3,188,94,0,1152,185,1,0,0,0,1153,1168,5,110,0,0,1154,1156,5, - 126,0,0,1155,1157,5,154,0,0,1156,1155,1,0,0,0,1156,1157,1,0,0,0, - 1157,1168,1,0,0,0,1158,1160,5,177,0,0,1159,1161,5,154,0,0,1160,1159, - 1,0,0,0,1160,1161,1,0,0,0,1161,1168,1,0,0,0,1162,1164,5,97,0,0,1163, - 1165,5,154,0,0,1164,1163,1,0,0,0,1164,1165,1,0,0,0,1165,1168,1,0, - 0,0,1166,1168,5,154,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, - 154,0,0,1176,1175,1,0,0,0,1176,1177,1,0,0,0,1177,1178,1,0,0,0,1178, - 1180,5,77,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,154,0,0,1185,1184,1,0,0,0,1185,1186,1,0,0,0,1186,1187,1,0, - 0,0,1187,1189,5,210,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,154,0,0,1194,1193,1,0,0,0,1194,1195,1,0,0,0,1195, - 1196,1,0,0,0,1196,1198,5,116,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,152,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,141,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,119,0,0,1270,1272,5,141,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,141,0,0,1276,1275,1,0,0,0,1276,1277,1,0,0,0,1277,1278,1,0, - 0,0,1278,1279,5,107,0,0,1279,1280,5,295,0,0,1280,1281,3,188,94,0, - 1281,1282,5,296,0,0,1282,1309,1,0,0,0,1283,1285,10,4,0,0,1284,1286, - 5,141,0,0,1285,1284,1,0,0,0,1285,1286,1,0,0,0,1286,1287,1,0,0,0, - 1287,1288,5,107,0,0,1288,1309,3,202,101,0,1289,1291,10,3,0,0,1290, - 1292,5,141,0,0,1291,1290,1,0,0,0,1291,1292,1,0,0,0,1292,1293,1,0, - 0,0,1293,1294,5,128,0,0,1294,1297,3,202,101,0,1295,1296,5,75,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,141,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,105,1,105,1,105,1,105,1,105,1,105,1,105,1,105,1,105,3,105,1384, + 8,105,1,105,1,105,4,105,1388,8,105,11,105,12,105,1389,5,105,1392, + 8,105,10,105,12,105,1395,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,1408,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,1422, + 8,108,10,108,12,108,1425,9,108,1,108,1,108,1,109,1,109,3,109,1431, + 8,109,1,109,1,109,1,109,1,109,1,109,4,109,1438,8,109,11,109,12,109, + 1439,1,109,1,109,3,109,1444,8,109,1,109,1,109,1,110,1,110,1,110, + 1,110,5,110,1452,8,110,10,110,12,110,1455,9,110,1,111,1,111,1,111, + 1,111,5,111,1461,8,111,10,111,12,111,1464,9,111,1,111,1,111,1,112, + 1,112,1,112,1,112,4,112,1472,8,112,11,112,12,112,1473,1,112,1,112, + 1,113,1,113,1,113,1,113,1,113,5,113,1483,8,113,10,113,12,113,1486, + 9,113,3,113,1488,8,113,1,113,1,113,1,114,1,114,1,114,1,114,1,114, + 1,114,1,114,3,114,1499,8,114,3,114,1501,8,114,1,114,1,114,1,114, + 1,114,1,114,1,114,1,114,1,114,1,114,3,114,1512,8,114,3,114,1514, + 8,114,1,114,1,114,3,114,1518,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,1534, + 8,115,1,116,1,116,1,116,1,116,1,116,1,116,1,116,1,116,1,116,3,116, + 1545,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,1558,8,116,1,116,1,116,3,116,1562,8,116,1,117, + 1,117,1,117,1,117,1,117,1,117,1,117,3,117,1571,8,117,1,117,1,117, + 1,117,3,117,1576,8,117,1,118,1,118,1,118,1,118,1,118,1,118,1,118, + 3,118,1585,8,118,3,118,1587,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,1623,8,123,1,123, + 3,123,1626,8,123,1,123,3,123,1629,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,1648,8,125,10,125,12,125,1651,9,125,3,125,1653, + 8,125,1,125,1,125,1,126,1,126,1,126,5,126,1660,8,126,10,126,12,126, + 1663,9,126,1,126,1,126,1,126,1,126,5,126,1669,8,126,10,126,12,126, + 1672,9,126,1,126,3,126,1675,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,1688,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,1703,8,131,1,131,1,131,3,131,1707,8,131,1,131,3,131,1710,8, + 131,1,132,1,132,1,133,1,133,3,133,1716,8,133,1,134,1,134,1,134,1, + 134,5,134,1722,8,134,10,134,12,134,1725,9,134,3,134,1727,8,134,1, + 134,1,134,1,135,1,135,1,135,1,135,5,135,1735,8,135,10,135,12,135, + 1738,9,135,3,135,1740,8,135,1,135,1,135,1,136,1,136,1,136,1,136, + 5,136,1748,8,136,10,136,12,136,1751,9,136,3,136,1753,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,1775,8,138, + 1,138,1,138,1,138,3,138,1780,8,138,1,138,1,138,1,138,1,138,1,138, + 3,138,1787,8,138,1,138,1,138,1,138,3,138,1792,8,138,1,138,3,138, + 1795,8,138,1,139,1,139,1,139,1,139,1,139,1,139,1,139,3,139,1804, + 8,139,1,139,1,139,1,139,1,139,1,139,3,139,1811,8,139,1,139,1,139, + 1,139,1,139,1,139,3,139,1818,8,139,1,139,3,139,1821,8,139,1,139, + 1,139,1,139,1,139,3,139,1827,8,139,1,139,1,139,1,139,3,139,1832, + 8,139,1,139,3,139,1835,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,144, + 146,148,150,152,154,156,158,160,162,164,166,168,170,172,174,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,278,0,21,1,0,304,305,2,0,4,4,248,248,1,0,249,250,2,0,4,4, + 68,68,2,0,11,11,63,63,2,0,91,91,124,124,2,0,4,4,8,8,2,0,272,272, + 278,278,2,0,282,285,287,288,2,0,280,280,286,286,1,0,272,273,2,0, + 274,275,278,278,1,0,267,268,7,0,8,8,15,15,44,44,76,76,132,133,190, + 190,197,197,1,0,231,232,1,0,87,88,12,0,19,19,28,29,44,44,53,54,83, + 83,130,130,146,146,174,174,188,188,196,196,208,208,214,214,9,0,8, + 8,26,27,53,53,114,115,142,142,171,171,189,189,237,237,252,269,3, + 0,26,27,92,92,221,221,2,0,56,57,145,145,1,0,202,203,2004,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,399,1,0,0,0,32,413,1,0,0,0,34,415,1,0,0,0, + 36,423,1,0,0,0,38,433,1,0,0,0,40,440,1,0,0,0,42,469,1,0,0,0,44,477, + 1,0,0,0,46,479,1,0,0,0,48,496,1,0,0,0,50,498,1,0,0,0,52,506,1,0, + 0,0,54,514,1,0,0,0,56,517,1,0,0,0,58,552,1,0,0,0,60,554,1,0,0,0, + 62,565,1,0,0,0,64,572,1,0,0,0,66,584,1,0,0,0,68,605,1,0,0,0,70,607, + 1,0,0,0,72,617,1,0,0,0,74,619,1,0,0,0,76,624,1,0,0,0,78,629,1,0, + 0,0,80,632,1,0,0,0,82,641,1,0,0,0,84,645,1,0,0,0,86,653,1,0,0,0, + 88,668,1,0,0,0,90,685,1,0,0,0,92,687,1,0,0,0,94,711,1,0,0,0,96,713, + 1,0,0,0,98,721,1,0,0,0,100,728,1,0,0,0,102,730,1,0,0,0,104,739,1, + 0,0,0,106,743,1,0,0,0,108,753,1,0,0,0,110,761,1,0,0,0,112,777,1, + 0,0,0,114,781,1,0,0,0,116,786,1,0,0,0,118,796,1,0,0,0,120,806,1, + 0,0,0,122,816,1,0,0,0,124,819,1,0,0,0,126,828,1,0,0,0,128,847,1, + 0,0,0,130,849,1,0,0,0,132,852,1,0,0,0,134,855,1,0,0,0,136,858,1, + 0,0,0,138,862,1,0,0,0,140,867,1,0,0,0,142,878,1,0,0,0,144,892,1, + 0,0,0,146,905,1,0,0,0,148,907,1,0,0,0,150,910,1,0,0,0,152,912,1, + 0,0,0,154,933,1,0,0,0,156,973,1,0,0,0,158,983,1,0,0,0,160,1019,1, + 0,0,0,162,1021,1,0,0,0,164,1034,1,0,0,0,166,1045,1,0,0,0,168,1059, + 1,0,0,0,170,1067,1,0,0,0,172,1081,1,0,0,0,174,1089,1,0,0,0,176,1116, + 1,0,0,0,178,1141,1,0,0,0,180,1143,1,0,0,0,182,1159,1,0,0,0,184,1161, + 1,0,0,0,186,1178,1,0,0,0,188,1180,1,0,0,0,190,1182,1,0,0,0,192,1244, + 1,0,0,0,194,1246,1,0,0,0,196,1257,1,0,0,0,198,1271,1,0,0,0,200,1273, + 1,0,0,0,202,1324,1,0,0,0,204,1335,1,0,0,0,206,1346,1,0,0,0,208,1360, + 1,0,0,0,210,1383,1,0,0,0,212,1407,1,0,0,0,214,1409,1,0,0,0,216,1416, + 1,0,0,0,218,1428,1,0,0,0,220,1447,1,0,0,0,222,1456,1,0,0,0,224,1467, + 1,0,0,0,226,1477,1,0,0,0,228,1517,1,0,0,0,230,1533,1,0,0,0,232,1561, + 1,0,0,0,234,1575,1,0,0,0,236,1577,1,0,0,0,238,1591,1,0,0,0,240,1598, + 1,0,0,0,242,1605,1,0,0,0,244,1612,1,0,0,0,246,1619,1,0,0,0,248,1633, + 1,0,0,0,250,1642,1,0,0,0,252,1674,1,0,0,0,254,1687,1,0,0,0,256,1689, + 1,0,0,0,258,1695,1,0,0,0,260,1699,1,0,0,0,262,1709,1,0,0,0,264,1711, + 1,0,0,0,266,1715,1,0,0,0,268,1717,1,0,0,0,270,1730,1,0,0,0,272,1743, + 1,0,0,0,274,1756,1,0,0,0,276,1794,1,0,0,0,278,1834,1,0,0,0,280,292, + 5,84,0,0,281,282,5,295,0,0,282,287,3,4,2,0,283,284,5,271,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,296,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,298,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,298,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,298,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,298,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,304,0, + 0,318,319,5,304,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,81, + 0,0,334,343,3,188,94,0,335,340,3,188,94,0,336,337,5,271,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,300,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,199,0,0,369, + 374,3,18,9,0,370,371,5,295,0,0,371,372,3,34,17,0,372,373,5,296,0, + 0,373,375,1,0,0,0,374,370,1,0,0,0,374,375,1,0,0,0,375,400,1,0,0, + 0,376,377,5,45,0,0,377,378,5,243,0,0,378,379,5,148,0,0,379,380,3, + 12,6,0,380,381,5,295,0,0,381,386,3,46,23,0,382,383,5,271,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,296,0,0,390, + 400,1,0,0,0,391,392,5,45,0,0,392,393,5,223,0,0,393,394,3,12,6,0, + 394,395,5,148,0,0,395,396,3,12,6,0,396,397,5,10,0,0,397,398,5,301, + 0,0,398,400,1,0,0,0,399,367,1,0,0,0,399,376,1,0,0,0,399,391,1,0, + 0,0,400,31,1,0,0,0,401,402,5,71,0,0,402,403,5,199,0,0,403,414,3, + 18,9,0,404,405,5,71,0,0,405,406,5,243,0,0,406,407,3,12,6,0,407,408, + 5,148,0,0,408,409,3,12,6,0,409,414,1,0,0,0,410,411,5,71,0,0,411, + 412,5,223,0,0,412,414,3,12,6,0,413,401,1,0,0,0,413,404,1,0,0,0,413, + 410,1,0,0,0,414,33,1,0,0,0,415,420,3,36,18,0,416,417,5,271,0,0,417, + 419,3,36,18,0,418,416,1,0,0,0,419,422,1,0,0,0,420,418,1,0,0,0,420, + 421,1,0,0,0,421,35,1,0,0,0,422,420,1,0,0,0,423,424,3,24,12,0,424, + 428,3,278,139,0,425,427,3,38,19,0,426,425,1,0,0,0,427,430,1,0,0, + 0,428,426,1,0,0,0,428,429,1,0,0,0,429,37,1,0,0,0,430,428,1,0,0,0, + 431,432,5,39,0,0,432,434,3,26,13,0,433,431,1,0,0,0,433,434,1,0,0, + 0,434,435,1,0,0,0,435,436,3,40,20,0,436,39,1,0,0,0,437,438,5,141, + 0,0,438,441,5,142,0,0,439,441,5,142,0,0,440,437,1,0,0,0,440,439, + 1,0,0,0,441,41,1,0,0,0,442,444,3,78,39,0,443,445,3,44,22,0,444,443, + 1,0,0,0,445,446,1,0,0,0,446,444,1,0,0,0,446,447,1,0,0,0,447,449, + 1,0,0,0,448,450,3,92,46,0,449,448,1,0,0,0,449,450,1,0,0,0,450,452, + 1,0,0,0,451,453,3,86,43,0,452,451,1,0,0,0,452,453,1,0,0,0,453,470, + 1,0,0,0,454,456,3,130,65,0,455,457,3,92,46,0,456,455,1,0,0,0,456, + 457,1,0,0,0,457,459,1,0,0,0,458,460,3,44,22,0,459,458,1,0,0,0,460, + 461,1,0,0,0,461,459,1,0,0,0,461,462,1,0,0,0,462,464,1,0,0,0,463, + 465,3,86,43,0,464,463,1,0,0,0,464,465,1,0,0,0,465,470,1,0,0,0,466, + 470,3,84,42,0,467,470,3,56,28,0,468,470,3,44,22,0,469,442,1,0,0, + 0,469,454,1,0,0,0,469,466,1,0,0,0,469,467,1,0,0,0,469,468,1,0,0, + 0,470,43,1,0,0,0,471,478,3,58,29,0,472,478,3,64,32,0,473,478,3,80, + 40,0,474,478,3,50,25,0,475,478,3,54,27,0,476,478,3,52,26,0,477,471, + 1,0,0,0,477,472,1,0,0,0,477,473,1,0,0,0,477,474,1,0,0,0,477,475, + 1,0,0,0,477,476,1,0,0,0,478,45,1,0,0,0,479,483,3,12,6,0,480,482, + 3,48,24,0,481,480,1,0,0,0,482,485,1,0,0,0,483,481,1,0,0,0,483,484, + 1,0,0,0,484,47,1,0,0,0,485,483,1,0,0,0,486,487,5,291,0,0,487,488, + 3,276,138,0,488,489,5,292,0,0,489,497,1,0,0,0,490,491,5,291,0,0, + 491,492,3,12,6,0,492,493,5,292,0,0,493,497,1,0,0,0,494,495,5,300, + 0,0,495,497,3,12,6,0,496,486,1,0,0,0,496,490,1,0,0,0,496,494,1,0, + 0,0,497,49,1,0,0,0,498,499,5,174,0,0,499,500,5,118,0,0,500,502,3, + 12,6,0,501,503,3,6,3,0,502,501,1,0,0,0,502,503,1,0,0,0,503,504,1, + 0,0,0,504,505,3,188,94,0,505,51,1,0,0,0,506,507,5,215,0,0,507,508, + 5,118,0,0,508,510,3,12,6,0,509,511,3,6,3,0,510,509,1,0,0,0,510,511, + 1,0,0,0,511,512,1,0,0,0,512,513,3,188,94,0,513,53,1,0,0,0,514,515, + 5,242,0,0,515,516,3,46,23,0,516,55,1,0,0,0,517,518,5,113,0,0,518, + 519,5,118,0,0,519,520,3,46,23,0,520,521,5,219,0,0,521,524,3,188, + 94,0,522,523,5,13,0,0,523,525,3,188,94,0,524,522,1,0,0,0,524,525, + 1,0,0,0,525,527,1,0,0,0,526,528,3,66,33,0,527,526,1,0,0,0,527,528, + 1,0,0,0,528,530,1,0,0,0,529,531,3,86,43,0,530,529,1,0,0,0,530,531, + 1,0,0,0,531,57,1,0,0,0,532,533,5,113,0,0,533,534,5,118,0,0,534,536, + 3,12,6,0,535,537,3,60,30,0,536,535,1,0,0,0,536,537,1,0,0,0,537,538, + 1,0,0,0,538,540,3,220,110,0,539,541,3,62,31,0,540,539,1,0,0,0,540, + 541,1,0,0,0,541,553,1,0,0,0,542,543,5,113,0,0,543,544,5,118,0,0, + 544,546,3,12,6,0,545,547,3,6,3,0,546,545,1,0,0,0,546,547,1,0,0,0, + 547,548,1,0,0,0,548,550,3,188,94,0,549,551,3,62,31,0,550,549,1,0, + 0,0,550,551,1,0,0,0,551,553,1,0,0,0,552,532,1,0,0,0,552,542,1,0, + 0,0,553,59,1,0,0,0,554,555,5,295,0,0,555,560,3,24,12,0,556,557,5, + 271,0,0,557,559,3,24,12,0,558,556,1,0,0,0,559,562,1,0,0,0,560,558, + 1,0,0,0,560,561,1,0,0,0,561,563,1,0,0,0,562,560,1,0,0,0,563,564, + 5,296,0,0,564,61,1,0,0,0,565,566,5,148,0,0,566,568,5,245,0,0,567, + 569,3,68,34,0,568,567,1,0,0,0,568,569,1,0,0,0,569,570,1,0,0,0,570, + 571,3,72,36,0,571,63,1,0,0,0,572,573,5,113,0,0,573,574,5,118,0,0, + 574,575,3,46,23,0,575,576,5,219,0,0,576,579,3,188,94,0,577,578,5, + 13,0,0,578,580,3,188,94,0,579,577,1,0,0,0,579,580,1,0,0,0,580,582, + 1,0,0,0,581,583,3,66,33,0,582,581,1,0,0,0,582,583,1,0,0,0,583,65, + 1,0,0,0,584,585,5,148,0,0,585,586,5,245,0,0,586,587,5,226,0,0,587, + 588,3,188,94,0,588,589,5,246,0,0,589,590,5,251,0,0,590,67,1,0,0, + 0,591,592,5,295,0,0,592,597,3,12,6,0,593,594,5,271,0,0,594,596,3, + 12,6,0,595,593,1,0,0,0,596,599,1,0,0,0,597,595,1,0,0,0,597,598,1, + 0,0,0,598,600,1,0,0,0,599,597,1,0,0,0,600,601,5,296,0,0,601,606, + 1,0,0,0,602,603,5,148,0,0,603,604,5,39,0,0,604,606,3,70,35,0,605, + 591,1,0,0,0,605,602,1,0,0,0,606,69,1,0,0,0,607,608,3,12,6,0,608, + 71,1,0,0,0,609,610,5,246,0,0,610,618,5,251,0,0,611,612,5,246,0,0, + 612,613,5,174,0,0,613,618,3,74,37,0,614,615,5,246,0,0,615,616,5, + 213,0,0,616,618,3,76,38,0,617,609,1,0,0,0,617,611,1,0,0,0,617,614, + 1,0,0,0,618,73,1,0,0,0,619,622,5,80,0,0,620,621,5,226,0,0,621,623, + 3,188,94,0,622,620,1,0,0,0,622,623,1,0,0,0,623,75,1,0,0,0,624,627, + 5,80,0,0,625,626,5,226,0,0,626,628,3,188,94,0,627,625,1,0,0,0,627, + 628,1,0,0,0,628,77,1,0,0,0,629,630,5,213,0,0,630,631,3,178,89,0, + 631,79,1,0,0,0,632,633,5,186,0,0,633,638,3,82,41,0,634,635,5,271, + 0,0,635,637,3,82,41,0,636,634,1,0,0,0,637,640,1,0,0,0,638,636,1, + 0,0,0,638,639,1,0,0,0,639,81,1,0,0,0,640,638,1,0,0,0,641,642,3,46, + 23,0,642,643,5,284,0,0,643,644,3,188,94,0,644,83,1,0,0,0,645,646, + 5,62,0,0,646,648,3,90,45,0,647,649,3,92,46,0,648,647,1,0,0,0,648, + 649,1,0,0,0,649,651,1,0,0,0,650,652,3,86,43,0,651,650,1,0,0,0,651, + 652,1,0,0,0,652,85,1,0,0,0,653,654,5,247,0,0,654,659,3,88,44,0,655, + 656,5,271,0,0,656,658,3,88,44,0,657,655,1,0,0,0,658,661,1,0,0,0, + 659,657,1,0,0,0,659,660,1,0,0,0,660,87,1,0,0,0,661,659,1,0,0,0,662, + 663,7,1,0,0,663,664,7,2,0,0,664,669,5,278,0,0,665,666,7,1,0,0,666, + 667,7,2,0,0,667,669,3,188,94,0,668,662,1,0,0,0,668,665,1,0,0,0,669, + 89,1,0,0,0,670,671,5,96,0,0,671,673,3,46,23,0,672,674,3,6,3,0,673, + 672,1,0,0,0,673,674,1,0,0,0,674,676,1,0,0,0,675,677,3,8,4,0,676, + 675,1,0,0,0,676,677,1,0,0,0,677,679,1,0,0,0,678,680,3,10,5,0,679, + 678,1,0,0,0,679,680,1,0,0,0,680,686,1,0,0,0,681,682,5,96,0,0,682, + 683,3,46,23,0,683,684,3,12,6,0,684,686,1,0,0,0,685,670,1,0,0,0,685, + 681,1,0,0,0,686,91,1,0,0,0,687,688,5,226,0,0,688,689,3,188,94,0, + 689,93,1,0,0,0,690,692,5,183,0,0,691,693,3,100,50,0,692,691,1,0, + 0,0,692,693,1,0,0,0,693,694,1,0,0,0,694,712,5,278,0,0,695,697,5, + 183,0,0,696,698,3,100,50,0,697,696,1,0,0,0,697,698,1,0,0,0,698,699, + 1,0,0,0,699,712,3,96,48,0,700,702,5,183,0,0,701,703,3,100,50,0,702, + 701,1,0,0,0,702,703,1,0,0,0,703,704,1,0,0,0,704,705,5,219,0,0,705, + 712,3,188,94,0,706,707,5,238,0,0,707,708,3,188,94,0,708,709,5,13, + 0,0,709,710,3,188,94,0,710,712,1,0,0,0,711,690,1,0,0,0,711,695,1, + 0,0,0,711,700,1,0,0,0,711,706,1,0,0,0,712,95,1,0,0,0,713,718,3,98, + 49,0,714,715,5,271,0,0,715,717,3,98,49,0,716,714,1,0,0,0,717,720, + 1,0,0,0,718,716,1,0,0,0,718,719,1,0,0,0,719,97,1,0,0,0,720,718,1, + 0,0,0,721,726,3,188,94,0,722,724,5,10,0,0,723,722,1,0,0,0,723,724, + 1,0,0,0,724,725,1,0,0,0,725,727,3,12,6,0,726,723,1,0,0,0,726,727, + 1,0,0,0,727,99,1,0,0,0,728,729,7,3,0,0,729,101,1,0,0,0,730,731,5, + 244,0,0,731,736,3,104,52,0,732,733,5,271,0,0,733,735,3,104,52,0, + 734,732,1,0,0,0,735,738,1,0,0,0,736,734,1,0,0,0,736,737,1,0,0,0, + 737,103,1,0,0,0,738,736,1,0,0,0,739,740,3,188,94,0,740,741,5,10, + 0,0,741,742,3,12,6,0,742,105,1,0,0,0,743,744,5,153,0,0,744,745,5, + 20,0,0,745,750,3,108,54,0,746,747,5,271,0,0,747,749,3,108,54,0,748, + 746,1,0,0,0,749,752,1,0,0,0,750,748,1,0,0,0,750,751,1,0,0,0,751, + 107,1,0,0,0,752,750,1,0,0,0,753,755,3,188,94,0,754,756,7,4,0,0,755, + 754,1,0,0,0,755,756,1,0,0,0,756,759,1,0,0,0,757,758,5,143,0,0,758, + 760,7,5,0,0,759,757,1,0,0,0,759,760,1,0,0,0,760,109,1,0,0,0,761, + 763,5,103,0,0,762,764,5,159,0,0,763,762,1,0,0,0,763,764,1,0,0,0, + 764,765,1,0,0,0,765,766,5,20,0,0,766,771,3,114,57,0,767,768,5,271, + 0,0,768,770,3,114,57,0,769,767,1,0,0,0,770,773,1,0,0,0,771,769,1, + 0,0,0,771,772,1,0,0,0,772,775,1,0,0,0,773,771,1,0,0,0,774,776,3, + 112,56,0,775,774,1,0,0,0,775,776,1,0,0,0,776,111,1,0,0,0,777,778, + 5,103,0,0,778,779,5,10,0,0,779,780,3,12,6,0,780,113,1,0,0,0,781, + 784,3,192,96,0,782,783,5,10,0,0,783,785,3,12,6,0,784,782,1,0,0,0, + 784,785,1,0,0,0,785,115,1,0,0,0,786,787,5,233,0,0,787,789,5,295, + 0,0,788,790,3,118,59,0,789,788,1,0,0,0,789,790,1,0,0,0,790,792,1, + 0,0,0,791,793,3,120,60,0,792,791,1,0,0,0,792,793,1,0,0,0,793,794, + 1,0,0,0,794,795,5,296,0,0,795,117,1,0,0,0,796,797,5,234,0,0,797, + 798,5,20,0,0,798,803,3,188,94,0,799,800,5,271,0,0,800,802,3,188, + 94,0,801,799,1,0,0,0,802,805,1,0,0,0,803,801,1,0,0,0,803,804,1,0, + 0,0,804,119,1,0,0,0,805,803,1,0,0,0,806,807,5,153,0,0,807,808,5, + 20,0,0,808,813,3,108,54,0,809,810,5,271,0,0,810,812,3,108,54,0,811, + 809,1,0,0,0,812,815,1,0,0,0,813,811,1,0,0,0,813,814,1,0,0,0,814, + 121,1,0,0,0,815,813,1,0,0,0,816,817,5,104,0,0,817,818,3,192,96,0, + 818,123,1,0,0,0,819,820,5,79,0,0,820,825,3,126,63,0,821,822,5,271, + 0,0,822,824,3,126,63,0,823,821,1,0,0,0,824,827,1,0,0,0,825,823,1, + 0,0,0,825,826,1,0,0,0,826,125,1,0,0,0,827,825,1,0,0,0,828,830,3, + 12,6,0,829,831,3,128,64,0,830,829,1,0,0,0,831,832,1,0,0,0,832,830, + 1,0,0,0,832,833,1,0,0,0,833,127,1,0,0,0,834,835,5,300,0,0,835,848, + 3,12,6,0,836,837,5,291,0,0,837,838,5,301,0,0,838,848,5,292,0,0,839, + 840,5,291,0,0,840,841,5,302,0,0,841,848,5,292,0,0,842,843,5,291, + 0,0,843,844,5,278,0,0,844,848,5,292,0,0,845,846,5,300,0,0,846,848, + 5,278,0,0,847,834,1,0,0,0,847,836,1,0,0,0,847,839,1,0,0,0,847,842, + 1,0,0,0,847,845,1,0,0,0,848,129,1,0,0,0,849,850,5,96,0,0,850,851, + 3,174,87,0,851,131,1,0,0,0,852,853,5,226,0,0,853,854,3,192,96,0, + 854,133,1,0,0,0,855,856,5,241,0,0,856,857,3,192,96,0,857,135,1,0, + 0,0,858,859,5,240,0,0,859,860,3,192,96,0,860,137,1,0,0,0,861,863, + 3,146,73,0,862,861,1,0,0,0,862,863,1,0,0,0,863,864,1,0,0,0,864,865, + 3,142,71,0,865,139,1,0,0,0,866,868,3,146,73,0,867,866,1,0,0,0,867, + 868,1,0,0,0,868,869,1,0,0,0,869,874,3,142,71,0,870,871,5,271,0,0, + 871,873,3,142,71,0,872,870,1,0,0,0,873,876,1,0,0,0,874,872,1,0,0, + 0,874,875,1,0,0,0,875,141,1,0,0,0,876,874,1,0,0,0,877,879,3,150, + 75,0,878,877,1,0,0,0,878,879,1,0,0,0,879,881,1,0,0,0,880,882,3,148, + 74,0,881,880,1,0,0,0,881,882,1,0,0,0,882,886,1,0,0,0,883,885,3,144, + 72,0,884,883,1,0,0,0,885,888,1,0,0,0,886,884,1,0,0,0,886,887,1,0, + 0,0,887,143,1,0,0,0,888,886,1,0,0,0,889,893,3,152,76,0,890,893,3, + 154,77,0,891,893,3,156,78,0,892,889,1,0,0,0,892,890,1,0,0,0,892, + 891,1,0,0,0,893,145,1,0,0,0,894,895,7,6,0,0,895,906,5,187,0,0,896, + 898,5,8,0,0,897,899,5,302,0,0,898,897,1,0,0,0,898,899,1,0,0,0,899, + 906,1,0,0,0,900,901,5,187,0,0,901,903,5,302,0,0,902,904,5,103,0, + 0,903,902,1,0,0,0,903,904,1,0,0,0,904,906,1,0,0,0,905,894,1,0,0, + 0,905,896,1,0,0,0,905,900,1,0,0,0,906,147,1,0,0,0,907,908,3,12,6, + 0,908,909,5,284,0,0,909,149,1,0,0,0,910,911,5,304,0,0,911,151,1, + 0,0,0,912,914,5,295,0,0,913,915,3,12,6,0,914,913,1,0,0,0,914,915, + 1,0,0,0,915,918,1,0,0,0,916,917,5,297,0,0,917,919,3,164,82,0,918, + 916,1,0,0,0,918,919,1,0,0,0,919,921,1,0,0,0,920,922,3,92,46,0,921, + 920,1,0,0,0,921,922,1,0,0,0,922,923,1,0,0,0,923,924,5,296,0,0,924, + 153,1,0,0,0,925,927,3,160,80,0,926,928,3,158,79,0,927,926,1,0,0, + 0,927,928,1,0,0,0,928,934,1,0,0,0,929,931,3,172,86,0,930,932,3,158, + 79,0,931,930,1,0,0,0,931,932,1,0,0,0,932,934,1,0,0,0,933,925,1,0, + 0,0,933,929,1,0,0,0,934,155,1,0,0,0,935,937,5,295,0,0,936,938,3, + 150,75,0,937,936,1,0,0,0,937,938,1,0,0,0,938,940,1,0,0,0,939,941, + 3,148,74,0,940,939,1,0,0,0,940,941,1,0,0,0,941,943,1,0,0,0,942,944, + 3,144,72,0,943,942,1,0,0,0,944,945,1,0,0,0,945,943,1,0,0,0,945,946, + 1,0,0,0,946,948,1,0,0,0,947,949,3,92,46,0,948,947,1,0,0,0,948,949, + 1,0,0,0,949,950,1,0,0,0,950,952,5,296,0,0,951,953,3,158,79,0,952, + 951,1,0,0,0,952,953,1,0,0,0,953,974,1,0,0,0,954,956,5,291,0,0,955, + 957,3,150,75,0,956,955,1,0,0,0,956,957,1,0,0,0,957,959,1,0,0,0,958, + 960,3,148,74,0,959,958,1,0,0,0,959,960,1,0,0,0,960,962,1,0,0,0,961, + 963,3,144,72,0,962,961,1,0,0,0,963,964,1,0,0,0,964,962,1,0,0,0,964, + 965,1,0,0,0,965,967,1,0,0,0,966,968,3,92,46,0,967,966,1,0,0,0,967, + 968,1,0,0,0,968,969,1,0,0,0,969,971,5,292,0,0,970,972,3,158,79,0, + 971,970,1,0,0,0,971,972,1,0,0,0,972,974,1,0,0,0,973,935,1,0,0,0, + 973,954,1,0,0,0,974,157,1,0,0,0,975,984,7,7,0,0,976,977,5,293,0, + 0,977,978,5,302,0,0,978,980,5,271,0,0,979,981,5,302,0,0,980,979, + 1,0,0,0,980,981,1,0,0,0,981,982,1,0,0,0,982,984,5,294,0,0,983,975, + 1,0,0,0,983,976,1,0,0,0,984,159,1,0,0,0,985,986,5,273,0,0,986,987, + 3,162,81,0,987,988,5,273,0,0,988,989,5,288,0,0,989,1020,1,0,0,0, + 990,991,5,277,0,0,991,992,3,162,81,0,992,993,5,277,0,0,993,1020, + 1,0,0,0,994,995,5,287,0,0,995,996,5,273,0,0,996,997,3,162,81,0,997, + 998,5,273,0,0,998,1020,1,0,0,0,999,1000,5,277,0,0,1000,1001,3,162, + 81,0,1001,1002,5,277,0,0,1002,1003,5,288,0,0,1003,1020,1,0,0,0,1004, + 1005,5,287,0,0,1005,1006,5,277,0,0,1006,1007,3,162,81,0,1007,1008, + 5,277,0,0,1008,1020,1,0,0,0,1009,1010,5,287,0,0,1010,1011,5,273, + 0,0,1011,1012,3,162,81,0,1012,1013,5,273,0,0,1013,1014,5,288,0,0, + 1014,1020,1,0,0,0,1015,1016,5,273,0,0,1016,1017,3,162,81,0,1017, + 1018,5,273,0,0,1018,1020,1,0,0,0,1019,985,1,0,0,0,1019,990,1,0,0, + 0,1019,994,1,0,0,0,1019,999,1,0,0,0,1019,1004,1,0,0,0,1019,1009, + 1,0,0,0,1019,1015,1,0,0,0,1020,161,1,0,0,0,1021,1023,5,291,0,0,1022, + 1024,3,12,6,0,1023,1022,1,0,0,0,1023,1024,1,0,0,0,1024,1027,1,0, + 0,0,1025,1026,5,297,0,0,1026,1028,3,164,82,0,1027,1025,1,0,0,0,1027, + 1028,1,0,0,0,1028,1030,1,0,0,0,1029,1031,3,92,46,0,1030,1029,1,0, + 0,0,1030,1031,1,0,0,0,1031,1032,1,0,0,0,1032,1033,5,292,0,0,1033, + 163,1,0,0,0,1034,1035,6,82,-1,0,1035,1036,3,166,83,0,1036,1042,1, + 0,0,0,1037,1038,10,2,0,0,1038,1039,5,279,0,0,1039,1041,3,166,83, + 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,165,1,0,0,0,1044,1042,1,0,0,0,1045,1046,6,83,-1,0,1046, + 1047,3,168,84,0,1047,1053,1,0,0,0,1048,1049,10,2,0,0,1049,1050,5, + 280,0,0,1050,1052,3,168,84,0,1051,1048,1,0,0,0,1052,1055,1,0,0,0, + 1053,1051,1,0,0,0,1053,1054,1,0,0,0,1054,167,1,0,0,0,1055,1053,1, + 0,0,0,1056,1057,5,281,0,0,1057,1060,3,170,85,0,1058,1060,3,170,85, + 0,1059,1056,1,0,0,0,1059,1058,1,0,0,0,1060,169,1,0,0,0,1061,1068, + 3,12,6,0,1062,1068,5,275,0,0,1063,1064,5,295,0,0,1064,1065,3,164, + 82,0,1065,1066,5,296,0,0,1066,1068,1,0,0,0,1067,1061,1,0,0,0,1067, + 1062,1,0,0,0,1067,1063,1,0,0,0,1068,171,1,0,0,0,1069,1082,5,277, + 0,0,1070,1071,5,277,0,0,1071,1082,5,288,0,0,1072,1073,5,287,0,0, + 1073,1082,5,277,0,0,1074,1076,5,287,0,0,1075,1074,1,0,0,0,1075,1076, + 1,0,0,0,1076,1077,1,0,0,0,1077,1079,5,273,0,0,1078,1080,5,288,0, + 0,1079,1078,1,0,0,0,1079,1080,1,0,0,0,1080,1082,1,0,0,0,1081,1069, + 1,0,0,0,1081,1070,1,0,0,0,1081,1072,1,0,0,0,1081,1075,1,0,0,0,1082, + 173,1,0,0,0,1083,1084,6,87,-1,0,1084,1090,3,176,88,0,1085,1086,5, + 295,0,0,1086,1087,3,174,87,0,1087,1088,5,296,0,0,1088,1090,1,0,0, + 0,1089,1083,1,0,0,0,1089,1085,1,0,0,0,1090,1111,1,0,0,0,1091,1093, + 10,5,0,0,1092,1094,3,186,93,0,1093,1092,1,0,0,0,1093,1094,1,0,0, + 0,1094,1095,1,0,0,0,1095,1096,5,46,0,0,1096,1097,5,121,0,0,1097, + 1110,3,182,91,0,1098,1099,10,4,0,0,1099,1100,5,271,0,0,1100,1110, + 3,182,91,0,1101,1103,10,3,0,0,1102,1104,3,186,93,0,1103,1102,1,0, + 0,0,1103,1104,1,0,0,0,1104,1105,1,0,0,0,1105,1106,5,121,0,0,1106, + 1107,3,182,91,0,1107,1108,3,184,92,0,1108,1110,1,0,0,0,1109,1091, + 1,0,0,0,1109,1098,1,0,0,0,1109,1101,1,0,0,0,1110,1113,1,0,0,0,1111, + 1109,1,0,0,0,1111,1112,1,0,0,0,1112,175,1,0,0,0,1113,1111,1,0,0, + 0,1114,1117,3,178,89,0,1115,1117,3,180,90,0,1116,1114,1,0,0,0,1116, + 1115,1,0,0,0,1117,177,1,0,0,0,1118,1119,3,192,96,0,1119,1120,3,12, + 6,0,1120,1142,1,0,0,0,1121,1123,3,192,96,0,1122,1124,3,6,3,0,1123, + 1122,1,0,0,0,1123,1124,1,0,0,0,1124,1126,1,0,0,0,1125,1127,3,8,4, + 0,1126,1125,1,0,0,0,1126,1127,1,0,0,0,1127,1129,1,0,0,0,1128,1130, + 3,10,5,0,1129,1128,1,0,0,0,1129,1130,1,0,0,0,1130,1142,1,0,0,0,1131, + 1133,3,258,129,0,1132,1134,3,6,3,0,1133,1132,1,0,0,0,1133,1134,1, + 0,0,0,1134,1136,1,0,0,0,1135,1137,3,8,4,0,1136,1135,1,0,0,0,1136, + 1137,1,0,0,0,1137,1139,1,0,0,0,1138,1140,3,10,5,0,1139,1138,1,0, + 0,0,1139,1140,1,0,0,0,1140,1142,1,0,0,0,1141,1118,1,0,0,0,1141,1121, + 1,0,0,0,1141,1131,1,0,0,0,1142,179,1,0,0,0,1143,1144,5,239,0,0,1144, + 1146,3,188,94,0,1145,1147,3,6,3,0,1146,1145,1,0,0,0,1146,1147,1, + 0,0,0,1147,1149,1,0,0,0,1148,1150,3,8,4,0,1149,1148,1,0,0,0,1149, + 1150,1,0,0,0,1150,1152,1,0,0,0,1151,1153,3,10,5,0,1152,1151,1,0, + 0,0,1152,1153,1,0,0,0,1153,181,1,0,0,0,1154,1160,3,176,88,0,1155, + 1156,5,295,0,0,1156,1157,3,174,87,0,1157,1158,5,296,0,0,1158,1160, + 1,0,0,0,1159,1154,1,0,0,0,1159,1155,1,0,0,0,1160,183,1,0,0,0,1161, + 1162,5,148,0,0,1162,1163,3,188,94,0,1163,185,1,0,0,0,1164,1179,5, + 110,0,0,1165,1167,5,126,0,0,1166,1168,5,154,0,0,1167,1166,1,0,0, + 0,1167,1168,1,0,0,0,1168,1179,1,0,0,0,1169,1171,5,177,0,0,1170,1172, + 5,154,0,0,1171,1170,1,0,0,0,1171,1172,1,0,0,0,1172,1179,1,0,0,0, + 1173,1175,5,97,0,0,1174,1176,5,154,0,0,1175,1174,1,0,0,0,1175,1176, + 1,0,0,0,1176,1179,1,0,0,0,1177,1179,5,154,0,0,1178,1164,1,0,0,0, + 1178,1165,1,0,0,0,1178,1169,1,0,0,0,1178,1173,1,0,0,0,1178,1177, + 1,0,0,0,1179,187,1,0,0,0,1180,1181,3,190,95,0,1181,189,1,0,0,0,1182, + 1183,6,95,-1,0,1183,1184,3,192,96,0,1184,1214,1,0,0,0,1185,1187, + 10,4,0,0,1186,1188,5,154,0,0,1187,1186,1,0,0,0,1187,1188,1,0,0,0, + 1188,1189,1,0,0,0,1189,1191,5,77,0,0,1190,1192,7,3,0,0,1191,1190, + 1,0,0,0,1191,1192,1,0,0,0,1192,1193,1,0,0,0,1193,1213,3,192,96,0, + 1194,1196,10,3,0,0,1195,1197,5,154,0,0,1196,1195,1,0,0,0,1196,1197, + 1,0,0,0,1197,1198,1,0,0,0,1198,1200,5,210,0,0,1199,1201,7,3,0,0, + 1200,1199,1,0,0,0,1200,1201,1,0,0,0,1201,1202,1,0,0,0,1202,1213, + 3,192,96,0,1203,1205,10,2,0,0,1204,1206,5,154,0,0,1205,1204,1,0, + 0,0,1205,1206,1,0,0,0,1206,1207,1,0,0,0,1207,1209,5,116,0,0,1208, + 1210,7,3,0,0,1209,1208,1,0,0,0,1209,1210,1,0,0,0,1210,1211,1,0,0, + 0,1211,1213,3,192,96,0,1212,1185,1,0,0,0,1212,1194,1,0,0,0,1212, + 1203,1,0,0,0,1213,1216,1,0,0,0,1214,1212,1,0,0,0,1214,1215,1,0,0, + 0,1215,191,1,0,0,0,1216,1214,1,0,0,0,1217,1219,3,94,47,0,1218,1220, + 3,124,62,0,1219,1218,1,0,0,0,1219,1220,1,0,0,0,1220,1221,1,0,0,0, + 1221,1223,3,130,65,0,1222,1224,3,102,51,0,1223,1222,1,0,0,0,1223, + 1224,1,0,0,0,1224,1226,1,0,0,0,1225,1227,3,132,66,0,1226,1225,1, + 0,0,0,1226,1227,1,0,0,0,1227,1229,1,0,0,0,1228,1230,3,110,55,0,1229, + 1228,1,0,0,0,1229,1230,1,0,0,0,1230,1232,1,0,0,0,1231,1233,3,122, + 61,0,1232,1231,1,0,0,0,1232,1233,1,0,0,0,1233,1235,1,0,0,0,1234, + 1236,3,106,53,0,1235,1234,1,0,0,0,1235,1236,1,0,0,0,1236,1238,1, + 0,0,0,1237,1239,3,136,68,0,1238,1237,1,0,0,0,1238,1239,1,0,0,0,1239, + 1241,1,0,0,0,1240,1242,3,134,67,0,1241,1240,1,0,0,0,1241,1242,1, + 0,0,0,1242,1245,1,0,0,0,1243,1245,3,194,97,0,1244,1217,1,0,0,0,1244, + 1243,1,0,0,0,1245,193,1,0,0,0,1246,1247,6,97,-1,0,1247,1248,3,196, + 98,0,1248,1254,1,0,0,0,1249,1250,10,2,0,0,1250,1251,5,152,0,0,1251, + 1253,3,196,98,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,195,1,0,0,0,1256,1254,1,0,0,0,1257, + 1258,6,98,-1,0,1258,1259,3,198,99,0,1259,1265,1,0,0,0,1260,1261, + 10,2,0,0,1261,1262,5,7,0,0,1262,1264,3,198,99,0,1263,1260,1,0,0, + 0,1264,1267,1,0,0,0,1265,1263,1,0,0,0,1265,1266,1,0,0,0,1266,197, + 1,0,0,0,1267,1265,1,0,0,0,1268,1269,5,141,0,0,1269,1272,3,198,99, + 0,1270,1272,3,200,100,0,1271,1268,1,0,0,0,1271,1270,1,0,0,0,1272, + 199,1,0,0,0,1273,1274,6,100,-1,0,1274,1275,3,202,101,0,1275,1321, + 1,0,0,0,1276,1277,10,7,0,0,1277,1278,7,8,0,0,1278,1320,3,202,101, + 0,1279,1280,10,6,0,0,1280,1282,5,119,0,0,1281,1283,5,141,0,0,1282, + 1281,1,0,0,0,1282,1283,1,0,0,0,1283,1284,1,0,0,0,1284,1320,3,278, + 139,0,1285,1287,10,5,0,0,1286,1288,5,141,0,0,1287,1286,1,0,0,0,1287, + 1288,1,0,0,0,1288,1289,1,0,0,0,1289,1290,5,107,0,0,1290,1291,5,295, + 0,0,1291,1292,3,188,94,0,1292,1293,5,296,0,0,1293,1320,1,0,0,0,1294, + 1296,10,4,0,0,1295,1297,5,141,0,0,1296,1295,1,0,0,0,1296,1297,1, + 0,0,0,1297,1298,1,0,0,0,1298,1299,5,107,0,0,1299,1320,3,202,101, + 0,1300,1302,10,3,0,0,1301,1303,5,141,0,0,1302,1301,1,0,0,0,1302, + 1303,1,0,0,0,1303,1304,1,0,0,0,1304,1305,5,128,0,0,1305,1308,3,202, + 101,0,1306,1307,5,75,0,0,1307,1309,3,188,94,0,1308,1306,1,0,0,0, + 1308,1309,1,0,0,0,1309,1320,1,0,0,0,1310,1312,10,2,0,0,1311,1313, + 5,141,0,0,1312,1311,1,0,0,0,1312,1313,1,0,0,0,1313,1314,1,0,0,0, + 1314,1315,5,17,0,0,1315,1316,3,202,101,0,1316,1317,5,7,0,0,1317, + 1318,3,202,101,0,1318,1320,1,0,0,0,1319,1276,1,0,0,0,1319,1279,1, + 0,0,0,1319,1285,1,0,0,0,1319,1294,1,0,0,0,1319,1300,1,0,0,0,1319, + 1310,1,0,0,0,1320,1323,1,0,0,0,1321,1319,1,0,0,0,1321,1322,1,0,0, + 0,1322,201,1,0,0,0,1323,1321,1,0,0,0,1324,1325,6,101,-1,0,1325,1326, + 3,204,102,0,1326,1332,1,0,0,0,1327,1328,10,2,0,0,1328,1329,7,9,0, + 0,1329,1331,3,204,102,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,203,1,0,0,0,1334,1332,1,0,0, + 0,1335,1336,6,102,-1,0,1336,1337,3,206,103,0,1337,1343,1,0,0,0,1338, + 1339,10,2,0,0,1339,1340,7,10,0,0,1340,1342,3,206,103,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,295,0,0,1386, - 1387,3,188,94,0,1387,1388,5,296,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,144,0,0,1399,1400, - 5,295,0,0,1400,1401,3,188,94,0,1401,1402,5,271,0,0,1402,1403,3,188, - 94,0,1403,1404,5,296,0,0,1404,215,1,0,0,0,1405,1406,5,32,0,0,1406, - 1407,5,295,0,0,1407,1412,3,188,94,0,1408,1409,5,271,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,296,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,224,0,0,1422,1423,3,188,94,0,1423,1424,5,201,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,72, - 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,73,0,0,1435,219,1,0,0,0,1436,1437,5,220, - 0,0,1437,1442,3,222,111,0,1438,1439,5,271,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,295,0,0,1446, - 1451,3,188,94,0,1447,1448,5,271,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,296,0,0,1455,223,1,0, - 0,0,1456,1457,5,295,0,0,1457,1460,3,188,94,0,1458,1459,5,271,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,296,0,0, - 1465,225,1,0,0,0,1466,1467,7,12,0,0,1467,1476,5,295,0,0,1468,1473, - 3,188,94,0,1469,1470,5,271,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,296,0,0,1479,227,1,0,0,0,1480,1481, - 5,196,0,0,1481,1482,5,295,0,0,1482,1489,3,188,94,0,1483,1484,5,271, - 0,0,1484,1487,3,188,94,0,1485,1486,5,271,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,296,0,0, - 1492,1507,1,0,0,0,1493,1494,5,196,0,0,1494,1495,5,295,0,0,1495,1502, - 3,188,94,0,1496,1497,5,96,0,0,1497,1500,3,188,94,0,1498,1499,5,93, - 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,296,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,161,0,0,1509,1510,5,295,0,0, - 1510,1511,3,188,94,0,1511,1512,5,271,0,0,1512,1513,3,188,94,0,1513, - 1514,5,296,0,0,1514,1523,1,0,0,0,1515,1516,5,161,0,0,1516,1517,5, - 295,0,0,1517,1518,3,188,94,0,1518,1519,5,107,0,0,1519,1520,3,188, - 94,0,1520,1521,5,296,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,157,0,0,1525,1526,5,295, - 0,0,1526,1527,3,188,94,0,1527,1528,5,271,0,0,1528,1529,3,188,94, - 0,1529,1530,5,271,0,0,1530,1533,3,188,94,0,1531,1532,5,271,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,296,0,0,1536,1551,1,0,0,0,1537,1538,5,157,0,0, - 1538,1539,5,295,0,0,1539,1540,3,188,94,0,1540,1541,5,160,0,0,1541, - 1542,3,188,94,0,1542,1543,5,96,0,0,1543,1546,3,188,94,0,1544,1545, - 5,93,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,296,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,295,0,0,1554,1555,5,278,0,0,1555,1565,5,296,0,0,1556,1557, - 7,13,0,0,1557,1559,5,295,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,296,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,295,0,0,1568, - 1575,3,188,94,0,1569,1570,5,271,0,0,1570,1573,3,188,94,0,1571,1572, - 5,271,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,296,0,0,1578,1579,3,116,58,0,1579,237,1,0,0, - 0,1580,1581,5,24,0,0,1581,1582,5,295,0,0,1582,1583,3,188,94,0,1583, - 1584,5,10,0,0,1584,1585,3,278,139,0,1585,1586,5,296,0,0,1586,239, - 1,0,0,0,1587,1588,5,236,0,0,1588,1589,5,295,0,0,1589,1590,3,188, - 94,0,1590,1591,5,10,0,0,1591,1592,3,278,139,0,1592,1593,5,296,0, - 0,1593,241,1,0,0,0,1594,1595,5,235,0,0,1595,1596,5,295,0,0,1596, - 1597,3,188,94,0,1597,1598,5,10,0,0,1598,1599,3,278,139,0,1599,1600, - 5,296,0,0,1600,243,1,0,0,0,1601,1602,5,86,0,0,1602,1603,5,295,0, - 0,1603,1604,5,304,0,0,1604,1605,5,96,0,0,1605,1606,3,188,94,0,1606, - 1607,5,296,0,0,1607,245,1,0,0,0,1608,1609,5,208,0,0,1609,1617,5, - 295,0,0,1610,1612,5,304,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,96,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, - 296,0,0,1621,247,1,0,0,0,1622,1623,7,15,0,0,1623,1624,5,295,0,0, - 1624,1625,5,304,0,0,1625,1626,5,271,0,0,1626,1627,3,188,94,0,1627, - 1628,5,271,0,0,1628,1629,3,188,94,0,1629,1630,5,296,0,0,1630,249, - 1,0,0,0,1631,1632,3,252,126,0,1632,1641,5,295,0,0,1633,1638,3,188, - 94,0,1634,1635,5,271,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,296,0,0,1644,251,1,0,0,0,1645,1646,3,12, - 6,0,1646,1647,5,300,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,300,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,291,0,0,1666,1667,3,188,94,0,1667,1668,5, - 292,0,0,1668,1677,1,0,0,0,1669,1670,5,291,0,0,1670,1671,5,278,0, - 0,1671,1677,5,292,0,0,1672,1673,5,300,0,0,1673,1677,3,12,6,0,1674, - 1675,5,300,0,0,1675,1677,5,278,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,295,0,0,1679,1680,3,210,105,0,1680,1681,5,131,0,0,1681,1682, - 3,140,70,0,1682,1683,5,296,0,0,1683,257,1,0,0,0,1684,1685,3,210, - 105,0,1685,1686,5,131,0,0,1686,1687,3,138,69,0,1687,259,1,0,0,0, - 1688,1689,5,299,0,0,1689,261,1,0,0,0,1690,1692,5,276,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,276,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,80,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,291,0,0,1707,1712,3,188,94,0,1708,1709, - 5,271,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,292,0,0,1718,269,1,0,0,0,1719,1728,5,289,0,0,1720,1725,3, - 188,94,0,1721,1722,5,271,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,290,0,0,1731,271,1,0,0,0,1732,1741,5,293, - 0,0,1733,1738,3,274,137,0,1734,1735,5,271,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,294,0,0,1744,273,1,0, - 0,0,1745,1746,3,188,94,0,1746,1747,5,297,0,0,1747,1748,3,188,94, - 0,1748,275,1,0,0,0,1749,1784,5,142,0,0,1750,1784,5,237,0,0,1751, - 1784,5,209,0,0,1752,1784,5,89,0,0,1753,1784,5,301,0,0,1754,1784, - 5,302,0,0,1755,1784,5,303,0,0,1756,1784,5,310,0,0,1757,1758,5,53, - 0,0,1758,1784,5,301,0,0,1759,1763,5,202,0,0,1760,1761,5,295,0,0, - 1761,1762,5,302,0,0,1762,1764,5,296,0,0,1763,1760,1,0,0,0,1763,1764, - 1,0,0,0,1764,1768,1,0,0,0,1765,1766,5,227,0,0,1766,1767,5,202,0, - 0,1767,1769,5,230,0,0,1768,1765,1,0,0,0,1768,1769,1,0,0,0,1769,1770, - 1,0,0,0,1770,1784,5,301,0,0,1771,1775,5,203,0,0,1772,1773,5,295, - 0,0,1773,1774,5,302,0,0,1774,1776,5,296,0,0,1775,1772,1,0,0,0,1775, - 1776,1,0,0,0,1776,1780,1,0,0,0,1777,1778,5,227,0,0,1778,1779,5,202, - 0,0,1779,1781,5,230,0,0,1780,1777,1,0,0,0,1780,1781,1,0,0,0,1781, - 1782,1,0,0,0,1782,1784,5,301,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,70,0,0,1787,1824,5,162,0,0,1788,1792,7,18,0,0,1789, - 1790,5,295,0,0,1790,1791,5,302,0,0,1791,1793,5,296,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,222,0,0,1796,1797,5,295,0,0,1797,1798,5,302,0,0,1798,1800, - 5,296,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,295,0,0,1803,1806,5,302,0,0,1804, - 1805,5,271,0,0,1805,1807,5,302,0,0,1806,1804,1,0,0,0,1806,1807,1, - 0,0,0,1807,1808,1,0,0,0,1808,1810,5,296,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,295, - 0,0,1813,1814,5,302,0,0,1814,1816,5,296,0,0,1815,1812,1,0,0,0,1815, - 1816,1,0,0,0,1816,1820,1,0,0,0,1817,1818,5,227,0,0,1818,1819,5,202, - 0,0,1819,1821,5,230,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 + 205,1,0,0,0,1345,1343,1,0,0,0,1346,1347,6,103,-1,0,1347,1348,3,208, + 104,0,1348,1354,1,0,0,0,1349,1350,10,2,0,0,1350,1351,7,11,0,0,1351, + 1353,3,208,104,0,1352,1349,1,0,0,0,1353,1356,1,0,0,0,1354,1352,1, + 0,0,0,1354,1355,1,0,0,0,1355,207,1,0,0,0,1356,1354,1,0,0,0,1357, + 1358,7,10,0,0,1358,1361,3,208,104,0,1359,1361,3,210,105,0,1360,1357, + 1,0,0,0,1360,1359,1,0,0,0,1361,209,1,0,0,0,1362,1363,6,105,-1,0, + 1363,1384,3,212,106,0,1364,1384,3,238,119,0,1365,1384,3,226,113, + 0,1366,1384,3,228,114,0,1367,1384,3,230,115,0,1368,1384,3,232,116, + 0,1369,1384,3,242,121,0,1370,1384,3,240,120,0,1371,1384,3,244,122, + 0,1372,1384,3,216,108,0,1373,1384,3,248,124,0,1374,1384,3,234,117, + 0,1375,1384,3,246,123,0,1376,1384,3,250,125,0,1377,1384,3,214,107, + 0,1378,1384,3,256,128,0,1379,1384,3,218,109,0,1380,1384,3,224,112, + 0,1381,1384,3,220,110,0,1382,1384,3,236,118,0,1383,1362,1,0,0,0, + 1383,1364,1,0,0,0,1383,1365,1,0,0,0,1383,1366,1,0,0,0,1383,1367, + 1,0,0,0,1383,1368,1,0,0,0,1383,1369,1,0,0,0,1383,1370,1,0,0,0,1383, + 1371,1,0,0,0,1383,1372,1,0,0,0,1383,1373,1,0,0,0,1383,1374,1,0,0, + 0,1383,1375,1,0,0,0,1383,1376,1,0,0,0,1383,1377,1,0,0,0,1383,1378, + 1,0,0,0,1383,1379,1,0,0,0,1383,1380,1,0,0,0,1383,1381,1,0,0,0,1383, + 1382,1,0,0,0,1384,1393,1,0,0,0,1385,1387,10,6,0,0,1386,1388,3,254, + 127,0,1387,1386,1,0,0,0,1388,1389,1,0,0,0,1389,1387,1,0,0,0,1389, + 1390,1,0,0,0,1390,1392,1,0,0,0,1391,1385,1,0,0,0,1392,1395,1,0,0, + 0,1393,1391,1,0,0,0,1393,1394,1,0,0,0,1394,211,1,0,0,0,1395,1393, + 1,0,0,0,1396,1397,5,295,0,0,1397,1398,3,188,94,0,1398,1399,5,296, + 0,0,1399,1408,1,0,0,0,1400,1408,5,51,0,0,1401,1408,5,48,0,0,1402, + 1408,3,260,130,0,1403,1408,3,262,131,0,1404,1408,3,276,138,0,1405, + 1408,3,266,133,0,1406,1408,3,272,136,0,1407,1396,1,0,0,0,1407,1400, + 1,0,0,0,1407,1401,1,0,0,0,1407,1402,1,0,0,0,1407,1403,1,0,0,0,1407, + 1404,1,0,0,0,1407,1405,1,0,0,0,1407,1406,1,0,0,0,1408,213,1,0,0, + 0,1409,1410,5,144,0,0,1410,1411,5,295,0,0,1411,1412,3,188,94,0,1412, + 1413,5,271,0,0,1413,1414,3,188,94,0,1414,1415,5,296,0,0,1415,215, + 1,0,0,0,1416,1417,5,32,0,0,1417,1418,5,295,0,0,1418,1423,3,188,94, + 0,1419,1420,5,271,0,0,1420,1422,3,188,94,0,1421,1419,1,0,0,0,1422, + 1425,1,0,0,0,1423,1421,1,0,0,0,1423,1424,1,0,0,0,1424,1426,1,0,0, + 0,1425,1423,1,0,0,0,1426,1427,5,296,0,0,1427,217,1,0,0,0,1428,1430, + 5,23,0,0,1429,1431,3,188,94,0,1430,1429,1,0,0,0,1430,1431,1,0,0, + 0,1431,1437,1,0,0,0,1432,1433,5,224,0,0,1433,1434,3,188,94,0,1434, + 1435,5,201,0,0,1435,1436,3,188,94,0,1436,1438,1,0,0,0,1437,1432, + 1,0,0,0,1438,1439,1,0,0,0,1439,1437,1,0,0,0,1439,1440,1,0,0,0,1440, + 1443,1,0,0,0,1441,1442,5,72,0,0,1442,1444,3,188,94,0,1443,1441,1, + 0,0,0,1443,1444,1,0,0,0,1444,1445,1,0,0,0,1445,1446,5,73,0,0,1446, + 219,1,0,0,0,1447,1448,5,220,0,0,1448,1453,3,222,111,0,1449,1450, + 5,271,0,0,1450,1452,3,222,111,0,1451,1449,1,0,0,0,1452,1455,1,0, + 0,0,1453,1451,1,0,0,0,1453,1454,1,0,0,0,1454,221,1,0,0,0,1455,1453, + 1,0,0,0,1456,1457,5,295,0,0,1457,1462,3,188,94,0,1458,1459,5,271, + 0,0,1459,1461,3,188,94,0,1460,1458,1,0,0,0,1461,1464,1,0,0,0,1462, + 1460,1,0,0,0,1462,1463,1,0,0,0,1463,1465,1,0,0,0,1464,1462,1,0,0, + 0,1465,1466,5,296,0,0,1466,223,1,0,0,0,1467,1468,5,295,0,0,1468, + 1471,3,188,94,0,1469,1470,5,271,0,0,1470,1472,3,188,94,0,1471,1469, + 1,0,0,0,1472,1473,1,0,0,0,1473,1471,1,0,0,0,1473,1474,1,0,0,0,1474, + 1475,1,0,0,0,1475,1476,5,296,0,0,1476,225,1,0,0,0,1477,1478,7,12, + 0,0,1478,1487,5,295,0,0,1479,1484,3,188,94,0,1480,1481,5,271,0,0, + 1481,1483,3,188,94,0,1482,1480,1,0,0,0,1483,1486,1,0,0,0,1484,1482, + 1,0,0,0,1484,1485,1,0,0,0,1485,1488,1,0,0,0,1486,1484,1,0,0,0,1487, + 1479,1,0,0,0,1487,1488,1,0,0,0,1488,1489,1,0,0,0,1489,1490,5,296, + 0,0,1490,227,1,0,0,0,1491,1492,5,196,0,0,1492,1493,5,295,0,0,1493, + 1500,3,188,94,0,1494,1495,5,271,0,0,1495,1498,3,188,94,0,1496,1497, + 5,271,0,0,1497,1499,3,188,94,0,1498,1496,1,0,0,0,1498,1499,1,0,0, + 0,1499,1501,1,0,0,0,1500,1494,1,0,0,0,1500,1501,1,0,0,0,1501,1502, + 1,0,0,0,1502,1503,5,296,0,0,1503,1518,1,0,0,0,1504,1505,5,196,0, + 0,1505,1506,5,295,0,0,1506,1513,3,188,94,0,1507,1508,5,96,0,0,1508, + 1511,3,188,94,0,1509,1510,5,93,0,0,1510,1512,3,188,94,0,1511,1509, + 1,0,0,0,1511,1512,1,0,0,0,1512,1514,1,0,0,0,1513,1507,1,0,0,0,1513, + 1514,1,0,0,0,1514,1515,1,0,0,0,1515,1516,5,296,0,0,1516,1518,1,0, + 0,0,1517,1491,1,0,0,0,1517,1504,1,0,0,0,1518,229,1,0,0,0,1519,1520, + 5,161,0,0,1520,1521,5,295,0,0,1521,1522,3,188,94,0,1522,1523,5,271, + 0,0,1523,1524,3,188,94,0,1524,1525,5,296,0,0,1525,1534,1,0,0,0,1526, + 1527,5,161,0,0,1527,1528,5,295,0,0,1528,1529,3,188,94,0,1529,1530, + 5,107,0,0,1530,1531,3,188,94,0,1531,1532,5,296,0,0,1532,1534,1,0, + 0,0,1533,1519,1,0,0,0,1533,1526,1,0,0,0,1534,231,1,0,0,0,1535,1536, + 5,157,0,0,1536,1537,5,295,0,0,1537,1538,3,188,94,0,1538,1539,5,271, + 0,0,1539,1540,3,188,94,0,1540,1541,5,271,0,0,1541,1544,3,188,94, + 0,1542,1543,5,271,0,0,1543,1545,3,188,94,0,1544,1542,1,0,0,0,1544, + 1545,1,0,0,0,1545,1546,1,0,0,0,1546,1547,5,296,0,0,1547,1562,1,0, + 0,0,1548,1549,5,157,0,0,1549,1550,5,295,0,0,1550,1551,3,188,94,0, + 1551,1552,5,160,0,0,1552,1553,3,188,94,0,1553,1554,5,96,0,0,1554, + 1557,3,188,94,0,1555,1556,5,93,0,0,1556,1558,3,188,94,0,1557,1555, + 1,0,0,0,1557,1558,1,0,0,0,1558,1559,1,0,0,0,1559,1560,5,296,0,0, + 1560,1562,1,0,0,0,1561,1535,1,0,0,0,1561,1548,1,0,0,0,1562,233,1, + 0,0,0,1563,1564,5,44,0,0,1564,1565,5,295,0,0,1565,1566,5,278,0,0, + 1566,1576,5,296,0,0,1567,1568,7,13,0,0,1568,1570,5,295,0,0,1569, + 1571,3,100,50,0,1570,1569,1,0,0,0,1570,1571,1,0,0,0,1571,1572,1, + 0,0,0,1572,1573,3,188,94,0,1573,1574,5,296,0,0,1574,1576,1,0,0,0, + 1575,1563,1,0,0,0,1575,1567,1,0,0,0,1576,235,1,0,0,0,1577,1578,7, + 14,0,0,1578,1579,5,295,0,0,1579,1586,3,188,94,0,1580,1581,5,271, + 0,0,1581,1584,3,188,94,0,1582,1583,5,271,0,0,1583,1585,3,188,94, + 0,1584,1582,1,0,0,0,1584,1585,1,0,0,0,1585,1587,1,0,0,0,1586,1580, + 1,0,0,0,1586,1587,1,0,0,0,1587,1588,1,0,0,0,1588,1589,5,296,0,0, + 1589,1590,3,116,58,0,1590,237,1,0,0,0,1591,1592,5,24,0,0,1592,1593, + 5,295,0,0,1593,1594,3,188,94,0,1594,1595,5,10,0,0,1595,1596,3,278, + 139,0,1596,1597,5,296,0,0,1597,239,1,0,0,0,1598,1599,5,236,0,0,1599, + 1600,5,295,0,0,1600,1601,3,188,94,0,1601,1602,5,10,0,0,1602,1603, + 3,278,139,0,1603,1604,5,296,0,0,1604,241,1,0,0,0,1605,1606,5,235, + 0,0,1606,1607,5,295,0,0,1607,1608,3,188,94,0,1608,1609,5,10,0,0, + 1609,1610,3,278,139,0,1610,1611,5,296,0,0,1611,243,1,0,0,0,1612, + 1613,5,86,0,0,1613,1614,5,295,0,0,1614,1615,5,304,0,0,1615,1616, + 5,96,0,0,1616,1617,3,188,94,0,1617,1618,5,296,0,0,1618,245,1,0,0, + 0,1619,1620,5,208,0,0,1620,1628,5,295,0,0,1621,1623,5,304,0,0,1622, + 1621,1,0,0,0,1622,1623,1,0,0,0,1623,1625,1,0,0,0,1624,1626,3,188, + 94,0,1625,1624,1,0,0,0,1625,1626,1,0,0,0,1626,1627,1,0,0,0,1627, + 1629,5,96,0,0,1628,1622,1,0,0,0,1628,1629,1,0,0,0,1629,1630,1,0, + 0,0,1630,1631,3,188,94,0,1631,1632,5,296,0,0,1632,247,1,0,0,0,1633, + 1634,7,15,0,0,1634,1635,5,295,0,0,1635,1636,5,304,0,0,1636,1637, + 5,271,0,0,1637,1638,3,188,94,0,1638,1639,5,271,0,0,1639,1640,3,188, + 94,0,1640,1641,5,296,0,0,1641,249,1,0,0,0,1642,1643,3,252,126,0, + 1643,1652,5,295,0,0,1644,1649,3,188,94,0,1645,1646,5,271,0,0,1646, + 1648,3,188,94,0,1647,1645,1,0,0,0,1648,1651,1,0,0,0,1649,1647,1, + 0,0,0,1649,1650,1,0,0,0,1650,1653,1,0,0,0,1651,1649,1,0,0,0,1652, + 1644,1,0,0,0,1652,1653,1,0,0,0,1653,1654,1,0,0,0,1654,1655,5,296, + 0,0,1655,251,1,0,0,0,1656,1657,3,12,6,0,1657,1658,5,300,0,0,1658, + 1660,1,0,0,0,1659,1656,1,0,0,0,1660,1663,1,0,0,0,1661,1659,1,0,0, + 0,1661,1662,1,0,0,0,1662,1664,1,0,0,0,1663,1661,1,0,0,0,1664,1675, + 7,16,0,0,1665,1666,3,12,6,0,1666,1667,5,300,0,0,1667,1669,1,0,0, + 0,1668,1665,1,0,0,0,1669,1672,1,0,0,0,1670,1668,1,0,0,0,1670,1671, + 1,0,0,0,1671,1673,1,0,0,0,1672,1670,1,0,0,0,1673,1675,3,12,6,0,1674, + 1661,1,0,0,0,1674,1670,1,0,0,0,1675,253,1,0,0,0,1676,1677,5,291, + 0,0,1677,1678,3,188,94,0,1678,1679,5,292,0,0,1679,1688,1,0,0,0,1680, + 1681,5,291,0,0,1681,1682,5,278,0,0,1682,1688,5,292,0,0,1683,1684, + 5,300,0,0,1684,1688,3,12,6,0,1685,1686,5,300,0,0,1686,1688,5,278, + 0,0,1687,1676,1,0,0,0,1687,1680,1,0,0,0,1687,1683,1,0,0,0,1687,1685, + 1,0,0,0,1688,255,1,0,0,0,1689,1690,5,295,0,0,1690,1691,3,210,105, + 0,1691,1692,5,131,0,0,1692,1693,3,140,70,0,1693,1694,5,296,0,0,1694, + 257,1,0,0,0,1695,1696,3,210,105,0,1696,1697,5,131,0,0,1697,1698, + 3,138,69,0,1698,259,1,0,0,0,1699,1700,5,299,0,0,1700,261,1,0,0,0, + 1701,1703,5,276,0,0,1702,1701,1,0,0,0,1702,1703,1,0,0,0,1703,1704, + 1,0,0,0,1704,1710,7,0,0,0,1705,1707,5,276,0,0,1706,1705,1,0,0,0, + 1706,1707,1,0,0,0,1707,1708,1,0,0,0,1708,1710,3,264,132,0,1709,1702, + 1,0,0,0,1709,1706,1,0,0,0,1710,263,1,0,0,0,1711,1712,5,80,0,0,1712, + 265,1,0,0,0,1713,1716,3,268,134,0,1714,1716,3,270,135,0,1715,1713, + 1,0,0,0,1715,1714,1,0,0,0,1716,267,1,0,0,0,1717,1726,5,291,0,0,1718, + 1723,3,188,94,0,1719,1720,5,271,0,0,1720,1722,3,188,94,0,1721,1719, + 1,0,0,0,1722,1725,1,0,0,0,1723,1721,1,0,0,0,1723,1724,1,0,0,0,1724, + 1727,1,0,0,0,1725,1723,1,0,0,0,1726,1718,1,0,0,0,1726,1727,1,0,0, + 0,1727,1728,1,0,0,0,1728,1729,5,292,0,0,1729,269,1,0,0,0,1730,1739, + 5,289,0,0,1731,1736,3,188,94,0,1732,1733,5,271,0,0,1733,1735,3,188, + 94,0,1734,1732,1,0,0,0,1735,1738,1,0,0,0,1736,1734,1,0,0,0,1736, + 1737,1,0,0,0,1737,1740,1,0,0,0,1738,1736,1,0,0,0,1739,1731,1,0,0, + 0,1739,1740,1,0,0,0,1740,1741,1,0,0,0,1741,1742,5,290,0,0,1742,271, + 1,0,0,0,1743,1752,5,293,0,0,1744,1749,3,274,137,0,1745,1746,5,271, + 0,0,1746,1748,3,274,137,0,1747,1745,1,0,0,0,1748,1751,1,0,0,0,1749, + 1747,1,0,0,0,1749,1750,1,0,0,0,1750,1753,1,0,0,0,1751,1749,1,0,0, + 0,1752,1744,1,0,0,0,1752,1753,1,0,0,0,1753,1754,1,0,0,0,1754,1755, + 5,294,0,0,1755,273,1,0,0,0,1756,1757,3,188,94,0,1757,1758,5,297, + 0,0,1758,1759,3,188,94,0,1759,275,1,0,0,0,1760,1795,5,142,0,0,1761, + 1795,5,237,0,0,1762,1795,5,209,0,0,1763,1795,5,89,0,0,1764,1795, + 5,301,0,0,1765,1795,5,302,0,0,1766,1795,5,303,0,0,1767,1795,5,310, + 0,0,1768,1769,5,53,0,0,1769,1795,5,301,0,0,1770,1774,5,202,0,0,1771, + 1772,5,295,0,0,1772,1773,5,302,0,0,1773,1775,5,296,0,0,1774,1771, + 1,0,0,0,1774,1775,1,0,0,0,1775,1779,1,0,0,0,1776,1777,5,227,0,0, + 1777,1778,5,202,0,0,1778,1780,5,230,0,0,1779,1776,1,0,0,0,1779,1780, + 1,0,0,0,1780,1781,1,0,0,0,1781,1795,5,301,0,0,1782,1786,5,203,0, + 0,1783,1784,5,295,0,0,1784,1785,5,302,0,0,1785,1787,5,296,0,0,1786, + 1783,1,0,0,0,1786,1787,1,0,0,0,1787,1791,1,0,0,0,1788,1789,5,227, + 0,0,1789,1790,5,202,0,0,1790,1792,5,230,0,0,1791,1788,1,0,0,0,1791, + 1792,1,0,0,0,1792,1793,1,0,0,0,1793,1795,5,301,0,0,1794,1760,1,0, + 0,0,1794,1761,1,0,0,0,1794,1762,1,0,0,0,1794,1763,1,0,0,0,1794,1764, + 1,0,0,0,1794,1765,1,0,0,0,1794,1766,1,0,0,0,1794,1767,1,0,0,0,1794, + 1768,1,0,0,0,1794,1770,1,0,0,0,1794,1782,1,0,0,0,1795,277,1,0,0, + 0,1796,1835,7,17,0,0,1797,1798,5,70,0,0,1798,1835,5,162,0,0,1799, + 1803,7,18,0,0,1800,1801,5,295,0,0,1801,1802,5,302,0,0,1802,1804, + 5,296,0,0,1803,1800,1,0,0,0,1803,1804,1,0,0,0,1804,1835,1,0,0,0, + 1805,1806,5,27,0,0,1806,1810,5,222,0,0,1807,1808,5,295,0,0,1808, + 1809,5,302,0,0,1809,1811,5,296,0,0,1810,1807,1,0,0,0,1810,1811,1, + 0,0,0,1811,1835,1,0,0,0,1812,1820,7,19,0,0,1813,1814,5,295,0,0,1814, + 1817,5,302,0,0,1815,1816,5,271,0,0,1816,1818,5,302,0,0,1817,1815, + 1,0,0,0,1817,1818,1,0,0,0,1818,1819,1,0,0,0,1819,1821,5,296,0,0, + 1820,1813,1,0,0,0,1820,1821,1,0,0,0,1821,1835,1,0,0,0,1822,1826, + 7,20,0,0,1823,1824,5,295,0,0,1824,1825,5,302,0,0,1825,1827,5,296, + 0,0,1826,1823,1,0,0,0,1826,1827,1,0,0,0,1827,1831,1,0,0,0,1828,1829, + 5,227,0,0,1829,1830,5,202,0,0,1830,1832,5,230,0,0,1831,1828,1,0, + 0,0,1831,1832,1,0,0,0,1832,1835,1,0,0,0,1833,1835,3,12,6,0,1834, + 1796,1,0,0,0,1834,1797,1,0,0,0,1834,1799,1,0,0,0,1834,1805,1,0,0, + 0,1834,1812,1,0,0,0,1834,1822,1,0,0,0,1834,1833,1,0,0,0,1835,279, + 1,0,0,0,230,287,292,294,301,305,309,313,315,340,343,350,365,374, + 386,399,413,420,428,433,440,446,449,452,456,461,464,469,477,483, + 496,502,510,524,527,530,536,540,546,550,552,560,568,579,582,597, + 605,617,622,627,638,648,651,659,668,673,676,679,685,692,697,702, + 711,718,723,726,736,750,755,759,763,771,775,784,789,792,803,813, + 825,832,847,862,867,874,878,881,886,892,898,903,905,914,918,921, + 927,931,933,937,940,945,948,952,956,959,964,967,971,973,980,983, + 1019,1023,1027,1030,1042,1053,1059,1067,1075,1079,1081,1089,1093, + 1103,1109,1111,1116,1123,1126,1129,1133,1136,1139,1141,1146,1149, + 1152,1159,1167,1171,1175,1178,1187,1191,1196,1200,1205,1209,1212, + 1214,1219,1223,1226,1229,1232,1235,1238,1241,1244,1254,1265,1271, + 1282,1287,1296,1302,1308,1312,1319,1321,1332,1343,1354,1360,1383, + 1389,1393,1407,1423,1430,1439,1443,1453,1462,1473,1484,1487,1498, + 1500,1511,1513,1517,1533,1544,1557,1561,1570,1575,1584,1586,1622, + 1625,1628,1649,1652,1661,1670,1674,1687,1702,1706,1709,1715,1723, + 1726,1736,1739,1749,1752,1774,1779,1786,1791,1794,1803,1810,1817, + 1820,1826,1831,1834 ] class PartiQLParser ( Parser ): @@ -1385,7 +1390,7 @@ class PartiQLParser ( Parser ): def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None @@ -2552,16 +2557,16 @@ def CREATE(self): return self.getToken(PartiQLParser.CREATE, 0) def VIEW(self): return self.getToken(PartiQLParser.VIEW, 0) - def ON(self): - return self.getToken(PartiQLParser.ON, 0) - def AS(self): - return self.getToken(PartiQLParser.AS, 0) def symbolPrimitive(self, i:int=None): if i is None: return self.getTypedRuleContexts(PartiQLParser.SymbolPrimitiveContext) else: return self.getTypedRuleContext(PartiQLParser.SymbolPrimitiveContext,i) + def ON(self): + return self.getToken(PartiQLParser.ON, 0) + def AS(self): + return self.getToken(PartiQLParser.AS, 0) def LITERAL_STRING(self): return self.getToken(PartiQLParser.LITERAL_STRING, 0) @@ -2580,13 +2585,14 @@ def accept(self, visitor:ParseTreeVisitor): return visitor.visitChildren(self) + def createCommand(self): localctx = PartiQLParser.CreateCommandContext(self, self._ctx, self.state) self.enterRule(localctx, 30, self.RULE_createCommand) self._la = 0 # Token type try: - self.state = 391 + self.state = 399 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,14,self._ctx) if la_ == 1: @@ -2643,6 +2649,25 @@ def createCommand(self): self.match(PartiQLParser.PAREN_RIGHT) pass + elif la_ == 3: + localctx = PartiQLParser.CreateViewContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 391 + self.match(PartiQLParser.CREATE) + self.state = 392 + self.match(PartiQLParser.VIEW) + self.state = 393 + self.symbolPrimitive() + self.state = 394 + self.match(PartiQLParser.ON) + self.state = 395 + self.symbolPrimitive() + self.state = 396 + self.match(PartiQLParser.AS) + self.state = 397 + self.match(PartiQLParser.LITERAL_STRING) + pass + except RecognitionException as re: localctx.exception = re @@ -2670,6 +2695,35 @@ def copyFrom(self, ctx:ParserRuleContext): + class DropViewContext(DropCommandContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a PartiQLParser.DropCommandContext + super().__init__(parser) + self.copyFrom(ctx) + + def DROP(self): + return self.getToken(PartiQLParser.DROP, 0) + def VIEW(self): + return self.getToken(PartiQLParser.VIEW, 0) + def symbolPrimitive(self): + return self.getTypedRuleContext(PartiQLParser.SymbolPrimitiveContext,0) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterDropView" ): + listener.enterDropView(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitDropView" ): + listener.exitDropView(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitDropView" ): + return visitor.visitDropView(self) + else: + return visitor.visitChildren(self) + + class DropTableContext(DropCommandContext): def __init__(self, parser, ctx:ParserRuleContext): # actually a PartiQLParser.DropCommandContext @@ -2735,69 +2789,52 @@ def accept(self, visitor:ParseTreeVisitor): return visitor.visitChildren(self) - class DropViewContext(DropCommandContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a PartiQLParser.DropCommandContext - super().__init__(parser) - self.copyFrom(ctx) - - def DROP(self): - return self.getToken(PartiQLParser.DROP, 0) - def VIEW(self): - return self.getToken(PartiQLParser.VIEW, 0) - def symbolPrimitive(self): - return self.getTypedRuleContext(PartiQLParser.SymbolPrimitiveContext,0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterDropView" ): - listener.enterDropView(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitDropView" ): - listener.exitDropView(self) - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitDropView" ): - return visitor.visitDropView(self) - else: - return visitor.visitChildren(self) - - def dropCommand(self): localctx = PartiQLParser.DropCommandContext(self, self._ctx, self.state) self.enterRule(localctx, 32, self.RULE_dropCommand) try: - self.state = 402 + self.state = 413 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 = 393 + self.state = 401 self.match(PartiQLParser.DROP) - self.state = 394 + self.state = 402 self.match(PartiQLParser.TABLE) - self.state = 395 + self.state = 403 self.qualifiedName() pass elif la_ == 2: localctx = PartiQLParser.DropIndexContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 396 + self.state = 404 self.match(PartiQLParser.DROP) - self.state = 397 + self.state = 405 self.match(PartiQLParser.INDEX) - self.state = 398 + self.state = 406 localctx.target = self.symbolPrimitive() - self.state = 399 + self.state = 407 self.match(PartiQLParser.ON) - self.state = 400 + self.state = 408 localctx.on = self.symbolPrimitive() pass + elif la_ == 3: + localctx = PartiQLParser.DropViewContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 410 + self.match(PartiQLParser.DROP) + self.state = 411 + self.match(PartiQLParser.VIEW) + self.state = 412 + self.symbolPrimitive() + pass + except RecognitionException as re: localctx.exception = re @@ -2855,17 +2892,17 @@ def tableDef(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 404 + self.state = 415 self.tableDefPart() - self.state = 409 + self.state = 420 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 405 + self.state = 416 self.match(PartiQLParser.COMMA) - self.state = 406 + self.state = 417 self.tableDefPart() - self.state = 411 + self.state = 422 self._errHandler.sync(self) _la = self._input.LA(1) @@ -2938,17 +2975,17 @@ def tableDefPart(self): try: localctx = PartiQLParser.ColumnDeclarationContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 412 + self.state = 423 self.columnName() - self.state = 413 + self.state = 424 self.type_() - self.state = 417 + self.state = 428 self._errHandler.sync(self) _la = self._input.LA(1) while _la==39 or _la==141 or _la==142: - self.state = 414 + self.state = 425 self.columnConstraint() - self.state = 419 + self.state = 430 self._errHandler.sync(self) _la = self._input.LA(1) @@ -3006,17 +3043,17 @@ def columnConstraint(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 422 + self.state = 433 self._errHandler.sync(self) _la = self._input.LA(1) if _la==39: - self.state = 420 + self.state = 431 self.match(PartiQLParser.CONSTRAINT) - self.state = 421 + self.state = 432 self.columnConstraintName() - self.state = 424 + self.state = 435 self.columnConstraintDef() except RecognitionException as re: localctx.exception = re @@ -3100,21 +3137,21 @@ def columnConstraintDef(self): localctx = PartiQLParser.ColumnConstraintDefContext(self, self._ctx, self.state) self.enterRule(localctx, 40, self.RULE_columnConstraintDef) try: - self.state = 429 + self.state = 440 self._errHandler.sync(self) token = self._input.LA(1) if token in [141]: localctx = PartiQLParser.ColConstrNotNullContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 426 + self.state = 437 self.match(PartiQLParser.NOT) - self.state = 427 + self.state = 438 self.match(PartiQLParser.NULL) pass elif token in [142]: localctx = PartiQLParser.ColConstrNullContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 428 + self.state = 439 self.match(PartiQLParser.NULL) pass else: @@ -3268,39 +3305,39 @@ def dml(self): self.enterRule(localctx, 42, self.RULE_dml) self._la = 0 # Token type try: - self.state = 458 + self.state = 469 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 = 431 + self.state = 442 self.updateClause() - self.state = 433 + self.state = 444 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 432 + self.state = 443 self.dmlBaseCommand() - self.state = 435 + self.state = 446 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==113 or _la==174 or ((((_la - 186)) & ~0x3f) == 0 and ((1 << (_la - 186)) & 72057594574798849) != 0)): break - self.state = 438 + self.state = 449 self._errHandler.sync(self) _la = self._input.LA(1) if _la==226: - self.state = 437 + self.state = 448 self.whereClause() - self.state = 441 + self.state = 452 self._errHandler.sync(self) _la = self._input.LA(1) if _la==247: - self.state = 440 + self.state = 451 self.returningClause() @@ -3309,33 +3346,33 @@ def dml(self): elif la_ == 2: localctx = PartiQLParser.DmlBaseWrapperContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 443 + self.state = 454 self.fromClause() - self.state = 445 + self.state = 456 self._errHandler.sync(self) _la = self._input.LA(1) if _la==226: - self.state = 444 + self.state = 455 self.whereClause() - self.state = 448 + self.state = 459 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 447 + self.state = 458 self.dmlBaseCommand() - self.state = 450 + self.state = 461 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==113 or _la==174 or ((((_la - 186)) & ~0x3f) == 0 and ((1 << (_la - 186)) & 72057594574798849) != 0)): break - self.state = 453 + self.state = 464 self._errHandler.sync(self) _la = self._input.LA(1) if _la==247: - self.state = 452 + self.state = 463 self.returningClause() @@ -3344,21 +3381,21 @@ def dml(self): elif la_ == 3: localctx = PartiQLParser.DmlDeleteContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 455 + self.state = 466 self.deleteCommand() pass elif la_ == 4: localctx = PartiQLParser.DmlInsertReturningContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 456 + self.state = 467 self.insertCommandReturning() pass elif la_ == 5: localctx = PartiQLParser.DmlBaseContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 457 + self.state = 468 self.dmlBaseCommand() pass @@ -3428,42 +3465,42 @@ def dmlBaseCommand(self): localctx = PartiQLParser.DmlBaseCommandContext(self, self._ctx, self.state) self.enterRule(localctx, 44, self.RULE_dmlBaseCommand) try: - self.state = 466 + self.state = 477 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,27,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 460 + self.state = 471 self.insertStatement() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 461 + self.state = 472 self.insertStatementLegacy() pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 462 + self.state = 473 self.setCommand() pass elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 463 + self.state = 474 self.replaceCommand() pass elif la_ == 5: self.enterOuterAlt(localctx, 5) - self.state = 464 + self.state = 475 self.removeCommand() pass elif la_ == 6: self.enterOuterAlt(localctx, 6) - self.state = 465 + self.state = 476 self.upsertCommand() pass @@ -3522,15 +3559,15 @@ def pathSimple(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 468 + self.state = 479 self.symbolPrimitive() - self.state = 472 + self.state = 483 self._errHandler.sync(self) _la = self._input.LA(1) while _la==291 or _la==300: - self.state = 469 + self.state = 480 self.pathSimpleSteps() - self.state = 474 + self.state = 485 self._errHandler.sync(self) _la = self._input.LA(1) @@ -3654,37 +3691,37 @@ def pathSimpleSteps(self): localctx = PartiQLParser.PathSimpleStepsContext(self, self._ctx, self.state) self.enterRule(localctx, 48, self.RULE_pathSimpleSteps) try: - self.state = 485 + self.state = 496 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 = 475 + self.state = 486 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 476 + self.state = 487 localctx.key = self.literal() - self.state = 477 + self.state = 488 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 2: localctx = PartiQLParser.PathSimpleSymbolContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 479 + self.state = 490 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 480 + self.state = 491 localctx.key = self.symbolPrimitive() - self.state = 481 + self.state = 492 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 3: localctx = PartiQLParser.PathSimpleDotSymbolContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 483 + self.state = 494 self.match(PartiQLParser.PERIOD) - self.state = 484 + self.state = 495 localctx.key = self.symbolPrimitive() pass @@ -3751,21 +3788,21 @@ def replaceCommand(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 487 + self.state = 498 self.match(PartiQLParser.REPLACE) - self.state = 488 + self.state = 499 self.match(PartiQLParser.INTO) - self.state = 489 + self.state = 500 self.symbolPrimitive() - self.state = 491 + self.state = 502 self._errHandler.sync(self) _la = self._input.LA(1) if _la==10: - self.state = 490 + self.state = 501 self.asIdent() - self.state = 493 + self.state = 504 localctx.value = self.expr() except RecognitionException as re: localctx.exception = re @@ -3829,21 +3866,21 @@ def upsertCommand(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 495 + self.state = 506 self.match(PartiQLParser.UPSERT) - self.state = 496 + self.state = 507 self.match(PartiQLParser.INTO) - self.state = 497 + self.state = 508 self.symbolPrimitive() - self.state = 499 + self.state = 510 self._errHandler.sync(self) _la = self._input.LA(1) if _la==10: - self.state = 498 + self.state = 509 self.asIdent() - self.state = 501 + self.state = 512 localctx.value = self.expr() except RecognitionException as re: localctx.exception = re @@ -3894,9 +3931,9 @@ def removeCommand(self): self.enterRule(localctx, 54, self.RULE_removeCommand) try: self.enterOuterAlt(localctx, 1) - self.state = 503 + self.state = 514 self.match(PartiQLParser.REMOVE) - self.state = 504 + self.state = 515 self.pathSimple() except RecognitionException as re: localctx.exception = re @@ -3974,39 +4011,39 @@ def insertCommandReturning(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 506 + self.state = 517 self.match(PartiQLParser.INSERT) - self.state = 507 + self.state = 518 self.match(PartiQLParser.INTO) - self.state = 508 + self.state = 519 self.pathSimple() - self.state = 509 + self.state = 520 self.match(PartiQLParser.VALUE) - self.state = 510 + self.state = 521 localctx.value = self.expr() - self.state = 513 + self.state = 524 self._errHandler.sync(self) _la = self._input.LA(1) if _la==13: - self.state = 511 + self.state = 522 self.match(PartiQLParser.AT) - self.state = 512 + self.state = 523 localctx.pos = self.expr() - self.state = 516 + self.state = 527 self._errHandler.sync(self) _la = self._input.LA(1) if _la==148: - self.state = 515 + self.state = 526 self.onConflictLegacy() - self.state = 519 + self.state = 530 self._errHandler.sync(self) _la = self._input.LA(1) if _la==247: - self.state = 518 + self.state = 529 self.returningClause() @@ -4083,32 +4120,32 @@ def insertStatement(self): self.enterRule(localctx, 58, self.RULE_insertStatement) self._la = 0 # Token type try: - self.state = 541 + self.state = 552 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,39,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 521 + self.state = 532 self.match(PartiQLParser.INSERT) - self.state = 522 + self.state = 533 self.match(PartiQLParser.INTO) - self.state = 523 + self.state = 534 self.symbolPrimitive() - self.state = 525 + self.state = 536 self._errHandler.sync(self) _la = self._input.LA(1) if _la==295: - self.state = 524 + self.state = 535 self.columnList() - self.state = 527 + self.state = 538 self.values() - self.state = 529 + self.state = 540 self._errHandler.sync(self) _la = self._input.LA(1) if _la==148: - self.state = 528 + self.state = 539 self.onConflict() @@ -4116,27 +4153,27 @@ def insertStatement(self): elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 531 + self.state = 542 self.match(PartiQLParser.INSERT) - self.state = 532 + self.state = 543 self.match(PartiQLParser.INTO) - self.state = 533 + self.state = 544 self.symbolPrimitive() - self.state = 535 + self.state = 546 self._errHandler.sync(self) _la = self._input.LA(1) if _la==10: - self.state = 534 + self.state = 545 self.asIdent() - self.state = 537 + self.state = 548 localctx.value = self.expr() - self.state = 539 + self.state = 550 self._errHandler.sync(self) _la = self._input.LA(1) if _la==148: - self.state = 538 + self.state = 549 self.onConflict() @@ -4205,23 +4242,23 @@ def columnList(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 543 + self.state = 554 self.match(PartiQLParser.PAREN_LEFT) - self.state = 544 + self.state = 555 self.columnName() - self.state = 549 + self.state = 560 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 545 + self.state = 556 self.match(PartiQLParser.COMMA) - self.state = 546 + self.state = 557 self.columnName() - self.state = 551 + self.state = 562 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 552 + self.state = 563 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -4280,19 +4317,19 @@ def onConflict(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 554 + self.state = 565 self.match(PartiQLParser.ON) - self.state = 555 + self.state = 566 self.match(PartiQLParser.CONFLICT) - self.state = 557 + self.state = 568 self._errHandler.sync(self) _la = self._input.LA(1) if _la==148 or _la==295: - self.state = 556 + self.state = 567 self.conflictTarget() - self.state = 559 + self.state = 570 self.conflictAction() except RecognitionException as re: localctx.exception = re @@ -4366,31 +4403,31 @@ def insertStatementLegacy(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 561 + self.state = 572 self.match(PartiQLParser.INSERT) - self.state = 562 + self.state = 573 self.match(PartiQLParser.INTO) - self.state = 563 + self.state = 574 self.pathSimple() - self.state = 564 + self.state = 575 self.match(PartiQLParser.VALUE) - self.state = 565 + self.state = 576 localctx.value = self.expr() - self.state = 568 + self.state = 579 self._errHandler.sync(self) _la = self._input.LA(1) if _la==13: - self.state = 566 + self.state = 577 self.match(PartiQLParser.AT) - self.state = 567 + self.state = 578 localctx.pos = self.expr() - self.state = 571 + self.state = 582 self._errHandler.sync(self) _la = self._input.LA(1) if _la==148: - self.state = 570 + self.state = 581 self.onConflictLegacy() @@ -4455,17 +4492,17 @@ def onConflictLegacy(self): self.enterRule(localctx, 66, self.RULE_onConflictLegacy) try: self.enterOuterAlt(localctx, 1) - self.state = 573 + self.state = 584 self.match(PartiQLParser.ON) - self.state = 574 + self.state = 585 self.match(PartiQLParser.CONFLICT) - self.state = 575 + self.state = 586 self.match(PartiQLParser.WHERE) - self.state = 576 + self.state = 587 self.expr() - self.state = 577 + self.state = 588 self.match(PartiQLParser.DO) - self.state = 578 + self.state = 589 self.match(PartiQLParser.NOTHING) except RecognitionException as re: localctx.exception = re @@ -4538,37 +4575,37 @@ def conflictTarget(self): self.enterRule(localctx, 68, self.RULE_conflictTarget) self._la = 0 # Token type try: - self.state = 594 + self.state = 605 self._errHandler.sync(self) token = self._input.LA(1) if token in [295]: self.enterOuterAlt(localctx, 1) - self.state = 580 + self.state = 591 self.match(PartiQLParser.PAREN_LEFT) - self.state = 581 + self.state = 592 self.symbolPrimitive() - self.state = 586 + self.state = 597 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 582 + self.state = 593 self.match(PartiQLParser.COMMA) - self.state = 583 + self.state = 594 self.symbolPrimitive() - self.state = 588 + self.state = 599 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 589 + self.state = 600 self.match(PartiQLParser.PAREN_RIGHT) pass elif token in [148]: self.enterOuterAlt(localctx, 2) - self.state = 591 + self.state = 602 self.match(PartiQLParser.ON) - self.state = 592 + self.state = 603 self.match(PartiQLParser.CONSTRAINT) - self.state = 593 + self.state = 604 self.constraintName() pass else: @@ -4620,7 +4657,7 @@ def constraintName(self): self.enterRule(localctx, 70, self.RULE_constraintName) try: self.enterOuterAlt(localctx, 1) - self.state = 596 + self.state = 607 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -4683,34 +4720,34 @@ def conflictAction(self): localctx = PartiQLParser.ConflictActionContext(self, self._ctx, self.state) self.enterRule(localctx, 72, self.RULE_conflictAction) try: - self.state = 606 + self.state = 617 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,46,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 598 + self.state = 609 self.match(PartiQLParser.DO) - self.state = 599 + self.state = 610 self.match(PartiQLParser.NOTHING) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 600 + self.state = 611 self.match(PartiQLParser.DO) - self.state = 601 + self.state = 612 self.match(PartiQLParser.REPLACE) - self.state = 602 + self.state = 613 self.doReplace() pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 603 + self.state = 614 self.match(PartiQLParser.DO) - self.state = 604 + self.state = 615 self.match(PartiQLParser.UPDATE) - self.state = 605 + self.state = 616 self.doUpdate() pass @@ -4768,15 +4805,15 @@ def doReplace(self): self.enterRule(localctx, 74, self.RULE_doReplace) try: self.enterOuterAlt(localctx, 1) - self.state = 608 + self.state = 619 self.match(PartiQLParser.EXCLUDED) - self.state = 611 + self.state = 622 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,47,self._ctx) if la_ == 1: - self.state = 609 + self.state = 620 self.match(PartiQLParser.WHERE) - self.state = 610 + self.state = 621 localctx.condition = self.expr() @@ -4833,15 +4870,15 @@ def doUpdate(self): self.enterRule(localctx, 76, self.RULE_doUpdate) try: self.enterOuterAlt(localctx, 1) - self.state = 613 + self.state = 624 self.match(PartiQLParser.EXCLUDED) - self.state = 616 + self.state = 627 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,48,self._ctx) if la_ == 1: - self.state = 614 + self.state = 625 self.match(PartiQLParser.WHERE) - self.state = 615 + self.state = 626 localctx.condition = self.expr() @@ -4894,9 +4931,9 @@ def updateClause(self): self.enterRule(localctx, 78, self.RULE_updateClause) try: self.enterOuterAlt(localctx, 1) - self.state = 618 + self.state = 629 self.match(PartiQLParser.UPDATE) - self.state = 619 + self.state = 630 self.tableBaseReference() except RecognitionException as re: localctx.exception = re @@ -4957,19 +4994,19 @@ def setCommand(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 621 + self.state = 632 self.match(PartiQLParser.SET) - self.state = 622 + self.state = 633 self.setAssignment() - self.state = 627 + self.state = 638 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 623 + self.state = 634 self.match(PartiQLParser.COMMA) - self.state = 624 + self.state = 635 self.setAssignment() - self.state = 629 + self.state = 640 self._errHandler.sync(self) _la = self._input.LA(1) @@ -5026,11 +5063,11 @@ def setAssignment(self): self.enterRule(localctx, 82, self.RULE_setAssignment) try: self.enterOuterAlt(localctx, 1) - self.state = 630 + self.state = 641 self.pathSimple() - self.state = 631 + self.state = 642 self.match(PartiQLParser.EQ) - self.state = 632 + self.state = 643 self.expr() except RecognitionException as re: localctx.exception = re @@ -5090,23 +5127,23 @@ def deleteCommand(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 634 + self.state = 645 self.match(PartiQLParser.DELETE) - self.state = 635 + self.state = 646 self.fromClauseSimple() - self.state = 637 + self.state = 648 self._errHandler.sync(self) _la = self._input.LA(1) if _la==226: - self.state = 636 + self.state = 647 self.whereClause() - self.state = 640 + self.state = 651 self._errHandler.sync(self) _la = self._input.LA(1) if _la==247: - self.state = 639 + self.state = 650 self.returningClause() @@ -5169,19 +5206,19 @@ def returningClause(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 642 + self.state = 653 self.match(PartiQLParser.RETURNING) - self.state = 643 + self.state = 654 self.returningColumn() - self.state = 648 + self.state = 659 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 644 + self.state = 655 self.match(PartiQLParser.COMMA) - self.state = 645 + self.state = 656 self.returningColumn() - self.state = 650 + self.state = 661 self._errHandler.sync(self) _la = self._input.LA(1) @@ -5249,12 +5286,12 @@ def returningColumn(self): self.enterRule(localctx, 88, self.RULE_returningColumn) self._la = 0 # Token type try: - self.state = 657 + self.state = 668 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,53,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 651 + self.state = 662 localctx.status = self._input.LT(1) _la = self._input.LA(1) if not(_la==4 or _la==248): @@ -5262,7 +5299,7 @@ def returningColumn(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 652 + self.state = 663 localctx.age = self._input.LT(1) _la = self._input.LA(1) if not(_la==249 or _la==250): @@ -5270,13 +5307,13 @@ def returningColumn(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 653 + self.state = 664 self.match(PartiQLParser.ASTERISK) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 654 + self.state = 665 localctx.status = self._input.LT(1) _la = self._input.LA(1) if not(_la==4 or _la==248): @@ -5284,7 +5321,7 @@ def returningColumn(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 655 + self.state = 666 localctx.age = self._input.LT(1) _la = self._input.LA(1) if not(_la==249 or _la==250): @@ -5292,7 +5329,7 @@ def returningColumn(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 656 + self.state = 667 localctx.col = self.expr() pass @@ -5396,37 +5433,37 @@ def fromClauseSimple(self): self.enterRule(localctx, 90, self.RULE_fromClauseSimple) self._la = 0 # Token type try: - self.state = 674 + self.state = 685 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,57,self._ctx) if la_ == 1: localctx = PartiQLParser.FromClauseSimpleExplicitContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 659 + self.state = 670 self.match(PartiQLParser.FROM) - self.state = 660 + self.state = 671 self.pathSimple() - self.state = 662 + self.state = 673 self._errHandler.sync(self) _la = self._input.LA(1) if _la==10: - self.state = 661 + self.state = 672 self.asIdent() - self.state = 665 + self.state = 676 self._errHandler.sync(self) _la = self._input.LA(1) if _la==13: - self.state = 664 + self.state = 675 self.atIdent() - self.state = 668 + self.state = 679 self._errHandler.sync(self) _la = self._input.LA(1) if _la==20: - self.state = 667 + self.state = 678 self.byIdent() @@ -5435,11 +5472,11 @@ def fromClauseSimple(self): elif la_ == 2: localctx = PartiQLParser.FromClauseSimpleImplicitContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 670 + self.state = 681 self.match(PartiQLParser.FROM) - self.state = 671 + self.state = 682 self.pathSimple() - self.state = 672 + self.state = 683 self.symbolPrimitive() pass @@ -5494,9 +5531,9 @@ def whereClause(self): self.enterRule(localctx, 92, self.RULE_whereClause) try: self.enterOuterAlt(localctx, 1) - self.state = 676 + self.state = 687 self.match(PartiQLParser.WHERE) - self.state = 677 + self.state = 688 localctx.arg = self.expr() except RecognitionException as re: localctx.exception = re @@ -5656,72 +5693,72 @@ def selectClause(self): self.enterRule(localctx, 94, self.RULE_selectClause) self._la = 0 # Token type try: - self.state = 700 + self.state = 711 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,61,self._ctx) if la_ == 1: localctx = PartiQLParser.SelectAllContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 679 + self.state = 690 self.match(PartiQLParser.SELECT) - self.state = 681 + self.state = 692 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==68: - self.state = 680 + self.state = 691 self.setQuantifierStrategy() - self.state = 683 + self.state = 694 self.match(PartiQLParser.ASTERISK) pass elif la_ == 2: localctx = PartiQLParser.SelectItemsContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 684 + self.state = 695 self.match(PartiQLParser.SELECT) - self.state = 686 + self.state = 697 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==68: - self.state = 685 + self.state = 696 self.setQuantifierStrategy() - self.state = 688 + self.state = 699 self.projectionItems() pass elif la_ == 3: localctx = PartiQLParser.SelectValueContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 689 + self.state = 700 self.match(PartiQLParser.SELECT) - self.state = 691 + self.state = 702 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==68: - self.state = 690 + self.state = 701 self.setQuantifierStrategy() - self.state = 693 + self.state = 704 self.match(PartiQLParser.VALUE) - self.state = 694 + self.state = 705 self.expr() pass elif la_ == 4: localctx = PartiQLParser.SelectPivotContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 695 + self.state = 706 self.match(PartiQLParser.PIVOT) - self.state = 696 + self.state = 707 localctx.pivot = self.expr() - self.state = 697 + self.state = 708 self.match(PartiQLParser.AT) - self.state = 698 + self.state = 709 localctx.at = self.expr() pass @@ -5782,17 +5819,17 @@ def projectionItems(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 702 + self.state = 713 self.projectionItem() - self.state = 707 + self.state = 718 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 703 + self.state = 714 self.match(PartiQLParser.COMMA) - self.state = 704 + self.state = 715 self.projectionItem() - self.state = 709 + self.state = 720 self._errHandler.sync(self) _la = self._input.LA(1) @@ -5850,21 +5887,21 @@ def projectionItem(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 710 + self.state = 721 self.expr() - self.state = 715 + self.state = 726 self._errHandler.sync(self) _la = self._input.LA(1) if _la==10 or _la==304 or _la==305: - self.state = 712 + self.state = 723 self._errHandler.sync(self) _la = self._input.LA(1) if _la==10: - self.state = 711 + self.state = 722 self.match(PartiQLParser.AS) - self.state = 714 + self.state = 725 self.symbolPrimitive() @@ -5917,7 +5954,7 @@ def setQuantifierStrategy(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 717 + self.state = 728 _la = self._input.LA(1) if not(_la==4 or _la==68): self._errHandler.recoverInline(self) @@ -5982,20 +6019,20 @@ def letClause(self): self.enterRule(localctx, 102, self.RULE_letClause) try: self.enterOuterAlt(localctx, 1) - self.state = 719 + self.state = 730 self.match(PartiQLParser.LET) - self.state = 720 + self.state = 731 self.letBinding() - self.state = 725 + self.state = 736 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,65,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 721 + self.state = 732 self.match(PartiQLParser.COMMA) - self.state = 722 + self.state = 733 self.letBinding() - self.state = 727 + self.state = 738 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,65,self._ctx) @@ -6052,11 +6089,11 @@ def letBinding(self): self.enterRule(localctx, 104, self.RULE_letBinding) try: self.enterOuterAlt(localctx, 1) - self.state = 728 + self.state = 739 self.expr() - self.state = 729 + self.state = 740 self.match(PartiQLParser.AS) - self.state = 730 + self.state = 741 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -6119,22 +6156,22 @@ def orderByClause(self): self.enterRule(localctx, 106, self.RULE_orderByClause) try: self.enterOuterAlt(localctx, 1) - self.state = 732 + self.state = 743 self.match(PartiQLParser.ORDER) - self.state = 733 + self.state = 744 self.match(PartiQLParser.BY) - self.state = 734 + self.state = 745 self.orderSortSpec() - self.state = 739 + self.state = 750 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,66,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 735 + self.state = 746 self.match(PartiQLParser.COMMA) - self.state = 736 + self.state = 747 self.orderSortSpec() - self.state = 741 + self.state = 752 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,66,self._ctx) @@ -6202,13 +6239,13 @@ def orderSortSpec(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 742 + self.state = 753 self.expr() - self.state = 744 + self.state = 755 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,67,self._ctx) if la_ == 1: - self.state = 743 + self.state = 754 localctx.dir_ = self._input.LT(1) _la = self._input.LA(1) if not(_la==11 or _la==63): @@ -6218,13 +6255,13 @@ def orderSortSpec(self): self.consume() - self.state = 748 + self.state = 759 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,68,self._ctx) if la_ == 1: - self.state = 746 + self.state = 757 self.match(PartiQLParser.NULLS) - self.state = 747 + self.state = 758 localctx.nulls = self._input.LT(1) _la = self._input.LA(1) if not(_la==91 or _la==124): @@ -6303,38 +6340,38 @@ def groupClause(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 750 + self.state = 761 self.match(PartiQLParser.GROUP) - self.state = 752 + self.state = 763 self._errHandler.sync(self) _la = self._input.LA(1) if _la==159: - self.state = 751 + self.state = 762 self.match(PartiQLParser.PARTIAL) - self.state = 754 + self.state = 765 self.match(PartiQLParser.BY) - self.state = 755 + self.state = 766 self.groupKey() - self.state = 760 + self.state = 771 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,70,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 756 + self.state = 767 self.match(PartiQLParser.COMMA) - self.state = 757 + self.state = 768 self.groupKey() - self.state = 762 + self.state = 773 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,70,self._ctx) - self.state = 764 + self.state = 775 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,71,self._ctx) if la_ == 1: - self.state = 763 + self.state = 774 self.groupAlias() @@ -6390,11 +6427,11 @@ def groupAlias(self): self.enterRule(localctx, 112, self.RULE_groupAlias) try: self.enterOuterAlt(localctx, 1) - self.state = 766 + self.state = 777 self.match(PartiQLParser.GROUP) - self.state = 767 + self.state = 778 self.match(PartiQLParser.AS) - self.state = 768 + self.state = 779 self.symbolPrimitive() except RecognitionException as re: localctx.exception = re @@ -6450,15 +6487,15 @@ def groupKey(self): self.enterRule(localctx, 114, self.RULE_groupKey) try: self.enterOuterAlt(localctx, 1) - self.state = 770 + self.state = 781 localctx.key = self.exprSelect() - self.state = 773 + self.state = 784 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,72,self._ctx) if la_ == 1: - self.state = 771 + self.state = 782 self.match(PartiQLParser.AS) - self.state = 772 + self.state = 783 self.symbolPrimitive() @@ -6522,27 +6559,27 @@ def over(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 775 + self.state = 786 self.match(PartiQLParser.OVER) - self.state = 776 + self.state = 787 self.match(PartiQLParser.PAREN_LEFT) - self.state = 778 + self.state = 789 self._errHandler.sync(self) _la = self._input.LA(1) if _la==234: - self.state = 777 + self.state = 788 self.windowPartitionList() - self.state = 781 + self.state = 792 self._errHandler.sync(self) _la = self._input.LA(1) if _la==153: - self.state = 780 + self.state = 791 self.windowSortSpecList() - self.state = 783 + self.state = 794 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -6606,21 +6643,21 @@ def windowPartitionList(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 785 + self.state = 796 self.match(PartiQLParser.PARTITION) - self.state = 786 + self.state = 797 self.match(PartiQLParser.BY) - self.state = 787 + self.state = 798 self.expr() - self.state = 792 + self.state = 803 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 788 + self.state = 799 self.match(PartiQLParser.COMMA) - self.state = 789 + self.state = 800 self.expr() - self.state = 794 + self.state = 805 self._errHandler.sync(self) _la = self._input.LA(1) @@ -6686,21 +6723,21 @@ def windowSortSpecList(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 795 + self.state = 806 self.match(PartiQLParser.ORDER) - self.state = 796 + self.state = 807 self.match(PartiQLParser.BY) - self.state = 797 + self.state = 808 self.orderSortSpec() - self.state = 802 + self.state = 813 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 798 + self.state = 809 self.match(PartiQLParser.COMMA) - self.state = 799 + self.state = 810 self.orderSortSpec() - self.state = 804 + self.state = 815 self._errHandler.sync(self) _la = self._input.LA(1) @@ -6754,9 +6791,9 @@ def havingClause(self): self.enterRule(localctx, 122, self.RULE_havingClause) try: self.enterOuterAlt(localctx, 1) - self.state = 805 + self.state = 816 self.match(PartiQLParser.HAVING) - self.state = 806 + self.state = 817 localctx.arg = self.exprSelect() except RecognitionException as re: localctx.exception = re @@ -6817,19 +6854,19 @@ def excludeClause(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 808 + self.state = 819 self.match(PartiQLParser.EXCLUDE) - self.state = 809 + self.state = 820 self.excludeExpr() - self.state = 814 + self.state = 825 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 810 + self.state = 821 self.match(PartiQLParser.COMMA) - self.state = 811 + self.state = 822 self.excludeExpr() - self.state = 816 + self.state = 827 self._errHandler.sync(self) _la = self._input.LA(1) @@ -6887,15 +6924,15 @@ def excludeExpr(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 817 + self.state = 828 self.symbolPrimitive() - self.state = 819 + self.state = 830 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 818 + self.state = 829 self.excludeExprSteps() - self.state = 821 + self.state = 832 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==291 or _la==300): @@ -7072,57 +7109,57 @@ def excludeExprSteps(self): localctx = PartiQLParser.ExcludeExprStepsContext(self, self._ctx, self.state) self.enterRule(localctx, 128, self.RULE_excludeExprSteps) try: - self.state = 836 + self.state = 847 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,79,self._ctx) if la_ == 1: localctx = PartiQLParser.ExcludeExprTupleAttrContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 823 + self.state = 834 self.match(PartiQLParser.PERIOD) - self.state = 824 + self.state = 835 self.symbolPrimitive() pass elif la_ == 2: localctx = PartiQLParser.ExcludeExprCollectionAttrContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 825 + self.state = 836 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 826 + self.state = 837 localctx.attr = self.match(PartiQLParser.LITERAL_STRING) - self.state = 827 + self.state = 838 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 3: localctx = PartiQLParser.ExcludeExprCollectionIndexContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 828 + self.state = 839 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 829 + self.state = 840 localctx.index = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 830 + self.state = 841 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 4: localctx = PartiQLParser.ExcludeExprCollectionWildcardContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 831 + self.state = 842 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 832 + self.state = 843 self.match(PartiQLParser.ASTERISK) - self.state = 833 + self.state = 844 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 5: localctx = PartiQLParser.ExcludeExprTupleWildcardContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 834 + self.state = 845 self.match(PartiQLParser.PERIOD) - self.state = 835 + self.state = 846 self.match(PartiQLParser.ASTERISK) pass @@ -7176,9 +7213,9 @@ def fromClause(self): self.enterRule(localctx, 130, self.RULE_fromClause) try: self.enterOuterAlt(localctx, 1) - self.state = 838 + self.state = 849 self.match(PartiQLParser.FROM) - self.state = 839 + self.state = 850 self.tableReference(0) except RecognitionException as re: localctx.exception = re @@ -7230,9 +7267,9 @@ def whereClauseSelect(self): self.enterRule(localctx, 132, self.RULE_whereClauseSelect) try: self.enterOuterAlt(localctx, 1) - self.state = 841 + self.state = 852 self.match(PartiQLParser.WHERE) - self.state = 842 + self.state = 853 localctx.arg = self.exprSelect() except RecognitionException as re: localctx.exception = re @@ -7284,9 +7321,9 @@ def offsetByClause(self): self.enterRule(localctx, 134, self.RULE_offsetByClause) try: self.enterOuterAlt(localctx, 1) - self.state = 844 + self.state = 855 self.match(PartiQLParser.OFFSET) - self.state = 845 + self.state = 856 localctx.arg = self.exprSelect() except RecognitionException as re: localctx.exception = re @@ -7338,9 +7375,9 @@ def limitClause(self): self.enterRule(localctx, 136, self.RULE_limitClause) try: self.enterOuterAlt(localctx, 1) - self.state = 847 + self.state = 858 self.match(PartiQLParser.LIMIT) - self.state = 848 + self.state = 859 localctx.arg = self.exprSelect() except RecognitionException as re: localctx.exception = re @@ -7393,15 +7430,15 @@ def gpmlPattern(self): self.enterRule(localctx, 138, self.RULE_gpmlPattern) try: self.enterOuterAlt(localctx, 1) - self.state = 851 + self.state = 862 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,80,self._ctx) if la_ == 1: - self.state = 850 + self.state = 861 localctx.selector = self.matchSelector() - self.state = 853 + self.state = 864 self.matchPattern() except RecognitionException as re: localctx.exception = re @@ -7464,25 +7501,25 @@ def gpmlPatternList(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 856 + self.state = 867 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==8 or _la==187: - self.state = 855 + self.state = 866 localctx.selector = self.matchSelector() - self.state = 858 + self.state = 869 self.matchPattern() - self.state = 863 + self.state = 874 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 859 + self.state = 870 self.match(PartiQLParser.COMMA) - self.state = 860 + self.state = 871 self.matchPattern() - self.state = 865 + self.state = 876 self._errHandler.sync(self) _la = self._input.LA(1) @@ -7545,30 +7582,30 @@ def matchPattern(self): self.enterRule(localctx, 142, self.RULE_matchPattern) try: self.enterOuterAlt(localctx, 1) - self.state = 867 + self.state = 878 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,83,self._ctx) if la_ == 1: - self.state = 866 + self.state = 877 localctx.restrictor = self.patternRestrictor() - self.state = 870 + self.state = 881 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,84,self._ctx) if la_ == 1: - self.state = 869 + self.state = 880 localctx.variable = self.patternPathVariable() - self.state = 875 + self.state = 886 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,85,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 872 + self.state = 883 self.graphPart() - self.state = 877 + self.state = 888 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,85,self._ctx) @@ -7625,24 +7662,24 @@ def graphPart(self): localctx = PartiQLParser.GraphPartContext(self, self._ctx, self.state) self.enterRule(localctx, 144, self.RULE_graphPart) try: - self.state = 881 + self.state = 892 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,86,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 878 + self.state = 889 self.node() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 879 + self.state = 890 self.edge() pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 880 + self.state = 891 self.pattern() pass @@ -7765,13 +7802,13 @@ def matchSelector(self): self.enterRule(localctx, 146, self.RULE_matchSelector) self._la = 0 # Token type try: - self.state = 894 + self.state = 905 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,89,self._ctx) if la_ == 1: localctx = PartiQLParser.SelectorBasicContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 883 + self.state = 894 localctx.mod = self._input.LT(1) _la = self._input.LA(1) if not(_la==4 or _la==8): @@ -7779,20 +7816,20 @@ def matchSelector(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 884 + self.state = 895 self.match(PartiQLParser.SHORTEST) pass elif la_ == 2: localctx = PartiQLParser.SelectorAnyContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 885 + self.state = 896 self.match(PartiQLParser.ANY) - self.state = 887 + self.state = 898 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,87,self._ctx) if la_ == 1: - self.state = 886 + self.state = 897 localctx.k = self.match(PartiQLParser.LITERAL_INTEGER) @@ -7801,15 +7838,15 @@ def matchSelector(self): elif la_ == 3: localctx = PartiQLParser.SelectorShortestContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 889 + self.state = 900 self.match(PartiQLParser.SHORTEST) - self.state = 890 + self.state = 901 localctx.k = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 892 + self.state = 903 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,88,self._ctx) if la_ == 1: - self.state = 891 + self.state = 902 self.match(PartiQLParser.GROUP) @@ -7865,9 +7902,9 @@ def patternPathVariable(self): self.enterRule(localctx, 148, self.RULE_patternPathVariable) try: self.enterOuterAlt(localctx, 1) - self.state = 896 + self.state = 907 self.symbolPrimitive() - self.state = 897 + self.state = 908 self.match(PartiQLParser.EQ) except RecognitionException as re: localctx.exception = re @@ -7915,7 +7952,7 @@ def patternRestrictor(self): self.enterRule(localctx, 150, self.RULE_patternRestrictor) try: self.enterOuterAlt(localctx, 1) - self.state = 899 + self.state = 910 localctx.restrictor = self.match(PartiQLParser.IDENTIFIER) except RecognitionException as re: localctx.exception = re @@ -7981,35 +8018,35 @@ def node(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 901 + self.state = 912 self.match(PartiQLParser.PAREN_LEFT) - self.state = 903 + self.state = 914 self._errHandler.sync(self) _la = self._input.LA(1) if _la==304 or _la==305: - self.state = 902 + self.state = 913 self.symbolPrimitive() - self.state = 907 + self.state = 918 self._errHandler.sync(self) _la = self._input.LA(1) if _la==297: - self.state = 905 + self.state = 916 self.match(PartiQLParser.COLON) - self.state = 906 + self.state = 917 self.labelSpec(0) - self.state = 910 + self.state = 921 self._errHandler.sync(self) _la = self._input.LA(1) if _la==226: - self.state = 909 + self.state = 920 self.whereClause() - self.state = 912 + self.state = 923 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -8101,19 +8138,19 @@ def edge(self): localctx = PartiQLParser.EdgeContext(self, self._ctx, self.state) self.enterRule(localctx, 154, self.RULE_edge) try: - self.state = 922 + self.state = 933 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,95,self._ctx) if la_ == 1: localctx = PartiQLParser.EdgeWithSpecContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 914 + self.state = 925 self.edgeWSpec() - self.state = 916 + self.state = 927 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,93,self._ctx) if la_ == 1: - self.state = 915 + self.state = 926 localctx.quantifier = self.patternQuantifier() @@ -8122,13 +8159,13 @@ def edge(self): elif la_ == 2: localctx = PartiQLParser.EdgeAbbreviatedContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 918 + self.state = 929 self.edgeAbbrev() - self.state = 920 + self.state = 931 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,94,self._ctx) if la_ == 1: - self.state = 919 + self.state = 930 localctx.quantifier = self.patternQuantifier() @@ -8216,107 +8253,107 @@ def pattern(self): self.enterRule(localctx, 156, self.RULE_pattern) self._la = 0 # Token type try: - self.state = 962 + self.state = 973 self._errHandler.sync(self) token = self._input.LA(1) if token in [295]: self.enterOuterAlt(localctx, 1) - self.state = 924 + self.state = 935 self.match(PartiQLParser.PAREN_LEFT) - self.state = 926 + self.state = 937 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,96,self._ctx) if la_ == 1: - self.state = 925 + self.state = 936 localctx.restrictor = self.patternRestrictor() - self.state = 929 + self.state = 940 self._errHandler.sync(self) _la = self._input.LA(1) if _la==304 or _la==305: - self.state = 928 + self.state = 939 localctx.variable = self.patternPathVariable() - self.state = 932 + self.state = 943 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 931 + self.state = 942 self.graphPart() - self.state = 934 + self.state = 945 self._errHandler.sync(self) _la = self._input.LA(1) if not (((((_la - 273)) & ~0x3f) == 0 and ((1 << (_la - 273)) & 4472849) != 0)): break - self.state = 937 + self.state = 948 self._errHandler.sync(self) _la = self._input.LA(1) if _la==226: - self.state = 936 + self.state = 947 localctx.where = self.whereClause() - self.state = 939 + self.state = 950 self.match(PartiQLParser.PAREN_RIGHT) - self.state = 941 + self.state = 952 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,100,self._ctx) if la_ == 1: - self.state = 940 + self.state = 951 localctx.quantifier = self.patternQuantifier() pass elif token in [291]: self.enterOuterAlt(localctx, 2) - self.state = 943 + self.state = 954 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 945 + self.state = 956 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,101,self._ctx) if la_ == 1: - self.state = 944 + self.state = 955 localctx.restrictor = self.patternRestrictor() - self.state = 948 + self.state = 959 self._errHandler.sync(self) _la = self._input.LA(1) if _la==304 or _la==305: - self.state = 947 + self.state = 958 localctx.variable = self.patternPathVariable() - self.state = 951 + self.state = 962 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 950 + self.state = 961 self.graphPart() - self.state = 953 + self.state = 964 self._errHandler.sync(self) _la = self._input.LA(1) if not (((((_la - 273)) & ~0x3f) == 0 and ((1 << (_la - 273)) & 4472849) != 0)): break - self.state = 956 + self.state = 967 self._errHandler.sync(self) _la = self._input.LA(1) if _la==226: - self.state = 955 + self.state = 966 localctx.where = self.whereClause() - self.state = 958 + self.state = 969 self.match(PartiQLParser.BRACKET_RIGHT) - self.state = 960 + self.state = 971 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,105,self._ctx) if la_ == 1: - self.state = 959 + self.state = 970 localctx.quantifier = self.patternQuantifier() @@ -8390,12 +8427,12 @@ def patternQuantifier(self): self.enterRule(localctx, 158, self.RULE_patternQuantifier) self._la = 0 # Token type try: - self.state = 972 + self.state = 983 self._errHandler.sync(self) token = self._input.LA(1) if token in [272, 278]: self.enterOuterAlt(localctx, 1) - self.state = 964 + self.state = 975 localctx.quant = self._input.LT(1) _la = self._input.LA(1) if not(_la==272 or _la==278): @@ -8406,21 +8443,21 @@ def patternQuantifier(self): pass elif token in [293]: self.enterOuterAlt(localctx, 2) - self.state = 965 + self.state = 976 self.match(PartiQLParser.BRACE_LEFT) - self.state = 966 + self.state = 977 localctx.lower = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 967 + self.state = 978 self.match(PartiQLParser.COMMA) - self.state = 969 + self.state = 980 self._errHandler.sync(self) _la = self._input.LA(1) if _la==302: - self.state = 968 + self.state = 979 localctx.upper = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 971 + self.state = 982 self.match(PartiQLParser.BRACE_RIGHT) pass else: @@ -8680,95 +8717,95 @@ def edgeWSpec(self): localctx = PartiQLParser.EdgeWSpecContext(self, self._ctx, self.state) self.enterRule(localctx, 160, self.RULE_edgeWSpec) try: - self.state = 1008 + self.state = 1019 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,109,self._ctx) if la_ == 1: localctx = PartiQLParser.EdgeSpecRightContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 974 + self.state = 985 self.match(PartiQLParser.MINUS) - self.state = 975 + self.state = 986 self.edgeSpec() - self.state = 976 + self.state = 987 self.match(PartiQLParser.MINUS) - self.state = 977 + self.state = 988 self.match(PartiQLParser.ANGLE_RIGHT) pass elif la_ == 2: localctx = PartiQLParser.EdgeSpecUndirectedContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 979 + self.state = 990 self.match(PartiQLParser.TILDE) - self.state = 980 + self.state = 991 self.edgeSpec() - self.state = 981 + self.state = 992 self.match(PartiQLParser.TILDE) pass elif la_ == 3: localctx = PartiQLParser.EdgeSpecLeftContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 983 + self.state = 994 self.match(PartiQLParser.ANGLE_LEFT) - self.state = 984 + self.state = 995 self.match(PartiQLParser.MINUS) - self.state = 985 + self.state = 996 self.edgeSpec() - self.state = 986 + self.state = 997 self.match(PartiQLParser.MINUS) pass elif la_ == 4: localctx = PartiQLParser.EdgeSpecUndirectedRightContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 988 + self.state = 999 self.match(PartiQLParser.TILDE) - self.state = 989 + self.state = 1000 self.edgeSpec() - self.state = 990 + self.state = 1001 self.match(PartiQLParser.TILDE) - self.state = 991 + self.state = 1002 self.match(PartiQLParser.ANGLE_RIGHT) pass elif la_ == 5: localctx = PartiQLParser.EdgeSpecUndirectedLeftContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 993 + self.state = 1004 self.match(PartiQLParser.ANGLE_LEFT) - self.state = 994 + self.state = 1005 self.match(PartiQLParser.TILDE) - self.state = 995 + self.state = 1006 self.edgeSpec() - self.state = 996 + self.state = 1007 self.match(PartiQLParser.TILDE) pass elif la_ == 6: localctx = PartiQLParser.EdgeSpecBidirectionalContext(self, localctx) self.enterOuterAlt(localctx, 6) - self.state = 998 + self.state = 1009 self.match(PartiQLParser.ANGLE_LEFT) - self.state = 999 + self.state = 1010 self.match(PartiQLParser.MINUS) - self.state = 1000 + self.state = 1011 self.edgeSpec() - self.state = 1001 + self.state = 1012 self.match(PartiQLParser.MINUS) - self.state = 1002 + self.state = 1013 self.match(PartiQLParser.ANGLE_RIGHT) pass elif la_ == 7: localctx = PartiQLParser.EdgeSpecUndirectedBidirectionalContext(self, localctx) self.enterOuterAlt(localctx, 7) - self.state = 1004 + self.state = 1015 self.match(PartiQLParser.MINUS) - self.state = 1005 + self.state = 1016 self.edgeSpec() - self.state = 1006 + self.state = 1017 self.match(PartiQLParser.MINUS) pass @@ -8837,35 +8874,35 @@ def edgeSpec(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1010 + self.state = 1021 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 1012 + self.state = 1023 self._errHandler.sync(self) _la = self._input.LA(1) if _la==304 or _la==305: - self.state = 1011 + self.state = 1022 self.symbolPrimitive() - self.state = 1016 + self.state = 1027 self._errHandler.sync(self) _la = self._input.LA(1) if _la==297: - self.state = 1014 + self.state = 1025 self.match(PartiQLParser.COLON) - self.state = 1015 + self.state = 1026 self.labelSpec(0) - self.state = 1019 + self.state = 1030 self._errHandler.sync(self) _la = self._input.LA(1) if _la==226: - self.state = 1018 + self.state = 1029 self.whereClause() - self.state = 1021 + self.state = 1032 self.match(PartiQLParser.BRACKET_RIGHT) except RecognitionException as re: localctx.exception = re @@ -8961,10 +8998,10 @@ def labelSpec(self, _p:int=0): self._ctx = localctx _prevctx = localctx - self.state = 1024 + self.state = 1035 self.labelTerm(0) self._ctx.stop = self._input.LT(-1) - self.state = 1031 + self.state = 1042 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,113,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -8974,15 +9011,15 @@ 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 = 1026 + 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 = 1027 + self.state = 1038 self.match(PartiQLParser.VERTBAR) - self.state = 1028 + self.state = 1039 self.labelTerm(0) - self.state = 1033 + self.state = 1044 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,113,self._ctx) @@ -9080,10 +9117,10 @@ def labelTerm(self, _p:int=0): self._ctx = localctx _prevctx = localctx - self.state = 1035 + self.state = 1046 self.labelFactor() self._ctx.stop = self._input.LT(-1) - self.state = 1042 + self.state = 1053 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,114,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -9093,15 +9130,15 @@ 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 = 1037 + self.state = 1048 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1038 + self.state = 1049 self.match(PartiQLParser.AMPERSAND) - self.state = 1039 + self.state = 1050 self.labelFactor() - self.state = 1044 + self.state = 1055 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,114,self._ctx) @@ -9189,21 +9226,21 @@ def labelFactor(self): localctx = PartiQLParser.LabelFactorContext(self, self._ctx, self.state) self.enterRule(localctx, 168, self.RULE_labelFactor) try: - self.state = 1048 + self.state = 1059 self._errHandler.sync(self) token = self._input.LA(1) if token in [281]: localctx = PartiQLParser.LabelFactorNotContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1045 + self.state = 1056 self.match(PartiQLParser.BANG) - self.state = 1046 + self.state = 1057 self.labelPrimary() pass elif token in [275, 295, 304, 305]: localctx = PartiQLParser.LabelFactorPrimaryContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1047 + self.state = 1058 self.labelPrimary() pass else: @@ -9319,29 +9356,29 @@ def labelPrimary(self): localctx = PartiQLParser.LabelPrimaryContext(self, self._ctx, self.state) self.enterRule(localctx, 170, self.RULE_labelPrimary) try: - self.state = 1056 + self.state = 1067 self._errHandler.sync(self) token = self._input.LA(1) if token in [304, 305]: localctx = PartiQLParser.LabelPrimaryNameContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1050 + self.state = 1061 self.symbolPrimitive() pass elif token in [275]: localctx = PartiQLParser.LabelPrimaryWildContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1051 + self.state = 1062 self.match(PartiQLParser.PERCENT) pass elif token in [295]: localctx = PartiQLParser.LabelPrimaryParenContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1052 + self.state = 1063 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1053 + self.state = 1064 self.labelSpec(0) - self.state = 1054 + self.state = 1065 self.match(PartiQLParser.PAREN_RIGHT) pass else: @@ -9401,48 +9438,48 @@ def edgeAbbrev(self): self.enterRule(localctx, 172, self.RULE_edgeAbbrev) self._la = 0 # Token type try: - self.state = 1070 + self.state = 1081 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,119,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 1058 + self.state = 1069 self.match(PartiQLParser.TILDE) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 1059 + self.state = 1070 self.match(PartiQLParser.TILDE) - self.state = 1060 + self.state = 1071 self.match(PartiQLParser.ANGLE_RIGHT) pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 1061 + self.state = 1072 self.match(PartiQLParser.ANGLE_LEFT) - self.state = 1062 + self.state = 1073 self.match(PartiQLParser.TILDE) pass elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 1064 + self.state = 1075 self._errHandler.sync(self) _la = self._input.LA(1) if _la==287: - self.state = 1063 + self.state = 1074 self.match(PartiQLParser.ANGLE_LEFT) - self.state = 1066 + self.state = 1077 self.match(PartiQLParser.MINUS) - self.state = 1068 + self.state = 1079 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,118,self._ctx) if la_ == 1: - self.state = 1067 + self.state = 1078 self.match(PartiQLParser.ANGLE_RIGHT) @@ -9616,7 +9653,7 @@ def tableReference(self, _p:int=0): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1078 + self.state = 1089 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,120,self._ctx) if la_ == 1: @@ -9624,7 +9661,7 @@ def tableReference(self, _p:int=0): self._ctx = localctx _prevctx = localctx - self.state = 1073 + self.state = 1084 self.tableNonJoin() pass @@ -9632,17 +9669,17 @@ def tableReference(self, _p:int=0): localctx = PartiQLParser.TableWrappedContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1074 + self.state = 1085 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1075 + self.state = 1086 self.tableReference(0) - self.state = 1076 + self.state = 1087 self.match(PartiQLParser.PAREN_RIGHT) pass self._ctx.stop = self._input.LT(-1) - self.state = 1100 + self.state = 1111 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,124,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -9650,30 +9687,30 @@ def tableReference(self, _p:int=0): if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 1098 + self.state = 1109 self._errHandler.sync(self) 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 = 1080 + self.state = 1091 if not self.precpred(self._ctx, 5): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") - self.state = 1082 + self.state = 1093 self._errHandler.sync(self) _la = self._input.LA(1) if ((((_la - 97)) & ~0x3f) == 0 and ((1 << (_la - 97)) & 144115188612734977) != 0) or _la==177: - self.state = 1081 + self.state = 1092 self.joinType() - self.state = 1084 + self.state = 1095 self.match(PartiQLParser.CROSS) - self.state = 1085 + self.state = 1096 self.match(PartiQLParser.JOIN) - self.state = 1086 + self.state = 1097 localctx.rhs = self.joinRhs() pass @@ -9681,13 +9718,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 = 1087 + self.state = 1098 if not self.precpred(self._ctx, 4): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") - self.state = 1088 + self.state = 1099 self.match(PartiQLParser.COMMA) - self.state = 1089 + self.state = 1100 localctx.rhs = self.joinRhs() pass @@ -9695,28 +9732,28 @@ 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 = 1090 + self.state = 1101 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 1092 + self.state = 1103 self._errHandler.sync(self) _la = self._input.LA(1) if ((((_la - 97)) & ~0x3f) == 0 and ((1 << (_la - 97)) & 144115188612734977) != 0) or _la==177: - self.state = 1091 + self.state = 1102 self.joinType() - self.state = 1094 + self.state = 1105 self.match(PartiQLParser.JOIN) - self.state = 1095 + self.state = 1106 localctx.rhs = self.joinRhs() - self.state = 1096 + self.state = 1107 self.joinSpec() pass - self.state = 1102 + self.state = 1113 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,124,self._ctx) @@ -9769,17 +9806,17 @@ def tableNonJoin(self): localctx = PartiQLParser.TableNonJoinContext(self, self._ctx, self.state) self.enterRule(localctx, 176, self.RULE_tableNonJoin) try: - self.state = 1105 + self.state = 1116 self._errHandler.sync(self) token = self._input.LA(1) if token in [8, 15, 19, 23, 24, 28, 29, 32, 44, 48, 51, 53, 54, 76, 80, 83, 86, 87, 88, 89, 130, 132, 133, 141, 142, 144, 146, 157, 161, 174, 183, 188, 190, 196, 197, 202, 203, 208, 209, 214, 220, 231, 232, 235, 236, 237, 238, 267, 268, 272, 273, 276, 289, 291, 293, 295, 299, 301, 302, 303, 304, 305, 310]: self.enterOuterAlt(localctx, 1) - self.state = 1103 + self.state = 1114 self.tableBaseReference() pass elif token in [239]: self.enterOuterAlt(localctx, 2) - self.state = 1104 + self.state = 1115 self.tableUnpivot() pass else: @@ -9916,44 +9953,44 @@ def tableBaseReference(self): localctx = PartiQLParser.TableBaseReferenceContext(self, self._ctx, self.state) self.enterRule(localctx, 178, self.RULE_tableBaseReference) try: - self.state = 1130 + self.state = 1141 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,132,self._ctx) if la_ == 1: localctx = PartiQLParser.TableBaseRefSymbolContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1107 + self.state = 1118 localctx.source = self.exprSelect() - self.state = 1108 + self.state = 1119 self.symbolPrimitive() pass elif la_ == 2: localctx = PartiQLParser.TableBaseRefClausesContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1110 + self.state = 1121 localctx.source = self.exprSelect() - self.state = 1112 + self.state = 1123 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,126,self._ctx) if la_ == 1: - self.state = 1111 + self.state = 1122 self.asIdent() - self.state = 1115 + self.state = 1126 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,127,self._ctx) if la_ == 1: - self.state = 1114 + self.state = 1125 self.atIdent() - self.state = 1118 + self.state = 1129 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,128,self._ctx) if la_ == 1: - self.state = 1117 + self.state = 1128 self.byIdent() @@ -9962,29 +9999,29 @@ def tableBaseReference(self): elif la_ == 3: localctx = PartiQLParser.TableBaseRefMatchContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1120 + self.state = 1131 localctx.source = self.exprGraphMatchOne() - self.state = 1122 + self.state = 1133 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,129,self._ctx) if la_ == 1: - self.state = 1121 + self.state = 1132 self.asIdent() - self.state = 1125 + self.state = 1136 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,130,self._ctx) if la_ == 1: - self.state = 1124 + self.state = 1135 self.atIdent() - self.state = 1128 + self.state = 1139 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,131,self._ctx) if la_ == 1: - self.state = 1127 + self.state = 1138 self.byIdent() @@ -10052,31 +10089,31 @@ def tableUnpivot(self): self.enterRule(localctx, 180, self.RULE_tableUnpivot) try: self.enterOuterAlt(localctx, 1) - self.state = 1132 + self.state = 1143 self.match(PartiQLParser.UNPIVOT) - self.state = 1133 + self.state = 1144 self.expr() - self.state = 1135 + self.state = 1146 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,133,self._ctx) if la_ == 1: - self.state = 1134 + self.state = 1145 self.asIdent() - self.state = 1138 + self.state = 1149 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,134,self._ctx) if la_ == 1: - self.state = 1137 + self.state = 1148 self.atIdent() - self.state = 1141 + self.state = 1152 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,135,self._ctx) if la_ == 1: - self.state = 1140 + self.state = 1151 self.byIdent() @@ -10166,24 +10203,24 @@ def joinRhs(self): localctx = PartiQLParser.JoinRhsContext(self, self._ctx, self.state) self.enterRule(localctx, 182, self.RULE_joinRhs) try: - self.state = 1148 + self.state = 1159 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,136,self._ctx) if la_ == 1: localctx = PartiQLParser.JoinRhsBaseContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1143 + self.state = 1154 self.tableNonJoin() pass elif la_ == 2: localctx = PartiQLParser.JoinRhsTableJoinedContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1144 + self.state = 1155 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1145 + self.state = 1156 self.tableReference(0) - self.state = 1146 + self.state = 1157 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -10237,9 +10274,9 @@ def joinSpec(self): self.enterRule(localctx, 184, self.RULE_joinSpec) try: self.enterOuterAlt(localctx, 1) - self.state = 1150 + self.state = 1161 self.match(PartiQLParser.ON) - self.state = 1151 + self.state = 1162 self.expr() except RecognitionException as re: localctx.exception = re @@ -10299,56 +10336,56 @@ def joinType(self): self.enterRule(localctx, 186, self.RULE_joinType) self._la = 0 # Token type try: - self.state = 1167 + self.state = 1178 self._errHandler.sync(self) token = self._input.LA(1) if token in [110]: self.enterOuterAlt(localctx, 1) - self.state = 1153 + self.state = 1164 localctx.mod = self.match(PartiQLParser.INNER) pass elif token in [126]: self.enterOuterAlt(localctx, 2) - self.state = 1154 + self.state = 1165 localctx.mod = self.match(PartiQLParser.LEFT) - self.state = 1156 + self.state = 1167 self._errHandler.sync(self) _la = self._input.LA(1) if _la==154: - self.state = 1155 + self.state = 1166 self.match(PartiQLParser.OUTER) pass elif token in [177]: self.enterOuterAlt(localctx, 3) - self.state = 1158 + self.state = 1169 localctx.mod = self.match(PartiQLParser.RIGHT) - self.state = 1160 + self.state = 1171 self._errHandler.sync(self) _la = self._input.LA(1) if _la==154: - self.state = 1159 + self.state = 1170 self.match(PartiQLParser.OUTER) pass elif token in [97]: self.enterOuterAlt(localctx, 4) - self.state = 1162 + self.state = 1173 localctx.mod = self.match(PartiQLParser.FULL) - self.state = 1164 + self.state = 1175 self._errHandler.sync(self) _la = self._input.LA(1) if _la==154: - self.state = 1163 + self.state = 1174 self.match(PartiQLParser.OUTER) pass elif token in [154]: self.enterOuterAlt(localctx, 5) - self.state = 1166 + self.state = 1177 localctx.mod = self.match(PartiQLParser.OUTER) pass else: @@ -10400,7 +10437,7 @@ def expr(self): self.enterRule(localctx, 188, self.RULE_expr) try: self.enterOuterAlt(localctx, 1) - self.state = 1169 + self.state = 1180 self.exprBagOp(0) except RecognitionException as re: localctx.exception = re @@ -10581,10 +10618,10 @@ def exprBagOp(self, _p:int=0): self._ctx = localctx _prevctx = localctx - self.state = 1172 + self.state = 1183 self.exprSelect() self._ctx.stop = self._input.LT(-1) - self.state = 1203 + self.state = 1214 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,148,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -10592,32 +10629,32 @@ def exprBagOp(self, _p:int=0): if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 1201 + self.state = 1212 self._errHandler.sync(self) 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 = 1174 + self.state = 1185 if not self.precpred(self._ctx, 4): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") - self.state = 1176 + self.state = 1187 self._errHandler.sync(self) _la = self._input.LA(1) if _la==154: - self.state = 1175 + self.state = 1186 self.match(PartiQLParser.OUTER) - self.state = 1178 + self.state = 1189 self.match(PartiQLParser.EXCEPT) - self.state = 1180 + self.state = 1191 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==68: - self.state = 1179 + self.state = 1190 _la = self._input.LA(1) if not(_la==4 or _la==68): self._errHandler.recoverInline(self) @@ -10626,7 +10663,7 @@ def exprBagOp(self, _p:int=0): self.consume() - self.state = 1182 + self.state = 1193 localctx.rhs = self.exprSelect() pass @@ -10634,25 +10671,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 = 1183 + self.state = 1194 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 1185 + self.state = 1196 self._errHandler.sync(self) _la = self._input.LA(1) if _la==154: - self.state = 1184 + self.state = 1195 self.match(PartiQLParser.OUTER) - self.state = 1187 + self.state = 1198 self.match(PartiQLParser.UNION) - self.state = 1189 + self.state = 1200 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==68: - self.state = 1188 + self.state = 1199 _la = self._input.LA(1) if not(_la==4 or _la==68): self._errHandler.recoverInline(self) @@ -10661,7 +10698,7 @@ def exprBagOp(self, _p:int=0): self.consume() - self.state = 1191 + self.state = 1202 localctx.rhs = self.exprSelect() pass @@ -10669,25 +10706,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 = 1192 + self.state = 1203 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1194 + self.state = 1205 self._errHandler.sync(self) _la = self._input.LA(1) if _la==154: - self.state = 1193 + self.state = 1204 self.match(PartiQLParser.OUTER) - self.state = 1196 + self.state = 1207 self.match(PartiQLParser.INTERSECT) - self.state = 1198 + self.state = 1209 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==68: - self.state = 1197 + self.state = 1208 _la = self._input.LA(1) if not(_la==4 or _la==68): self._errHandler.recoverInline(self) @@ -10696,12 +10733,12 @@ def exprBagOp(self, _p:int=0): self.consume() - self.state = 1200 + self.state = 1211 localctx.rhs = self.exprSelect() pass - self.state = 1205 + self.state = 1216 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,148,self._ctx) @@ -10825,77 +10862,77 @@ def exprSelect(self): self.enterRule(localctx, 192, self.RULE_exprSelect) self._la = 0 # Token type try: - self.state = 1233 + self.state = 1244 self._errHandler.sync(self) token = self._input.LA(1) if token in [183, 238]: localctx = PartiQLParser.SfwQueryContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1206 + self.state = 1217 localctx.select = self.selectClause() - self.state = 1208 + self.state = 1219 self._errHandler.sync(self) _la = self._input.LA(1) if _la==79: - self.state = 1207 + self.state = 1218 localctx.exclude = self.excludeClause() - self.state = 1210 + self.state = 1221 localctx.from_ = self.fromClause() - self.state = 1212 + self.state = 1223 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,150,self._ctx) if la_ == 1: - self.state = 1211 + self.state = 1222 localctx.let = self.letClause() - self.state = 1215 + self.state = 1226 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,151,self._ctx) if la_ == 1: - self.state = 1214 + self.state = 1225 localctx.where = self.whereClauseSelect() - self.state = 1218 + self.state = 1229 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,152,self._ctx) if la_ == 1: - self.state = 1217 + self.state = 1228 localctx.group = self.groupClause() - self.state = 1221 + self.state = 1232 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,153,self._ctx) if la_ == 1: - self.state = 1220 + self.state = 1231 localctx.having = self.havingClause() - self.state = 1224 + self.state = 1235 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,154,self._ctx) if la_ == 1: - self.state = 1223 + self.state = 1234 localctx.order = self.orderByClause() - self.state = 1227 + self.state = 1238 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,155,self._ctx) if la_ == 1: - self.state = 1226 + self.state = 1237 localctx.limit = self.limitClause() - self.state = 1230 + self.state = 1241 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,156,self._ctx) if la_ == 1: - self.state = 1229 + self.state = 1240 localctx.offset = self.offsetByClause() @@ -10903,7 +10940,7 @@ def exprSelect(self): elif token in [8, 15, 19, 23, 24, 28, 29, 32, 44, 48, 51, 53, 54, 76, 80, 83, 86, 87, 88, 89, 130, 132, 133, 141, 142, 144, 146, 157, 161, 174, 188, 190, 196, 197, 202, 203, 208, 209, 214, 220, 231, 232, 235, 236, 237, 267, 268, 272, 273, 276, 289, 291, 293, 295, 299, 301, 302, 303, 304, 305, 310]: localctx = PartiQLParser.SfwBaseContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1232 + self.state = 1243 self.exprOr(0) pass else: @@ -11006,10 +11043,10 @@ def exprOr(self, _p:int=0): self._ctx = localctx _prevctx = localctx - self.state = 1236 + self.state = 1247 localctx.parent_ = self.exprAnd(0) self._ctx.stop = self._input.LT(-1) - self.state = 1243 + self.state = 1254 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,158,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -11020,15 +11057,15 @@ 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 = 1238 + 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 = 1239 + self.state = 1250 self.match(PartiQLParser.OR) - self.state = 1240 + self.state = 1251 localctx.rhs = self.exprAnd(0) - self.state = 1245 + self.state = 1256 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,158,self._ctx) @@ -11130,10 +11167,10 @@ def exprAnd(self, _p:int=0): self._ctx = localctx _prevctx = localctx - self.state = 1247 + self.state = 1258 localctx.parent_ = self.exprNot() self._ctx.stop = self._input.LT(-1) - self.state = 1254 + self.state = 1265 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,159,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -11144,15 +11181,15 @@ 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 = 1249 + self.state = 1260 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1250 + self.state = 1261 localctx.op = self.match(PartiQLParser.AND) - self.state = 1251 + self.state = 1262 localctx.rhs = self.exprNot() - self.state = 1256 + self.state = 1267 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,159,self._ctx) @@ -11243,21 +11280,21 @@ def exprNot(self): localctx = PartiQLParser.ExprNotContext(self, self._ctx, self.state) self.enterRule(localctx, 198, self.RULE_exprNot) try: - self.state = 1260 + self.state = 1271 self._errHandler.sync(self) token = self._input.LA(1) if token in [141]: localctx = PartiQLParser.NotContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1257 + self.state = 1268 localctx.op = self.match(PartiQLParser.NOT) - self.state = 1258 + self.state = 1269 localctx.rhs = self.exprNot() pass elif token in [8, 15, 19, 23, 24, 28, 29, 32, 44, 48, 51, 53, 54, 76, 80, 83, 86, 87, 88, 89, 130, 132, 133, 142, 144, 146, 157, 161, 174, 188, 190, 196, 197, 202, 203, 208, 209, 214, 220, 231, 232, 235, 236, 237, 267, 268, 272, 273, 276, 289, 291, 293, 295, 299, 301, 302, 303, 304, 305, 310]: localctx = PartiQLParser.ExprNotBaseContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1259 + self.state = 1270 localctx.parent_ = self.exprPredicate(0) pass else: @@ -11526,10 +11563,10 @@ def exprPredicate(self, _p:int=0): self._ctx = localctx _prevctx = localctx - self.state = 1263 + self.state = 1274 localctx.parent_ = self.mathOp00(0) self._ctx.stop = self._input.LT(-1) - self.state = 1310 + self.state = 1321 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,168,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -11537,18 +11574,18 @@ def exprPredicate(self, _p:int=0): if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 1308 + self.state = 1319 self._errHandler.sync(self) 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 = 1265 + self.state = 1276 if not self.precpred(self._ctx, 7): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 7)") - self.state = 1266 + self.state = 1277 localctx.op = self._input.LT(1) _la = self._input.LA(1) if not(((((_la - 282)) & ~0x3f) == 0 and ((1 << (_la - 282)) & 111) != 0)): @@ -11556,7 +11593,7 @@ def exprPredicate(self, _p:int=0): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1267 + self.state = 1278 localctx.rhs = self.mathOp00(0) pass @@ -11564,21 +11601,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 = 1268 + self.state = 1279 if not self.precpred(self._ctx, 6): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 6)") - self.state = 1269 + self.state = 1280 self.match(PartiQLParser.IS) - self.state = 1271 + self.state = 1282 self._errHandler.sync(self) _la = self._input.LA(1) if _la==141: - self.state = 1270 + self.state = 1281 self.match(PartiQLParser.NOT) - self.state = 1273 + self.state = 1284 self.type_() pass @@ -11586,25 +11623,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 = 1274 + self.state = 1285 if not self.precpred(self._ctx, 5): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") - self.state = 1276 + self.state = 1287 self._errHandler.sync(self) _la = self._input.LA(1) if _la==141: - self.state = 1275 + self.state = 1286 self.match(PartiQLParser.NOT) - self.state = 1278 + self.state = 1289 self.match(PartiQLParser.IN) - self.state = 1279 + self.state = 1290 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1280 + self.state = 1291 self.expr() - self.state = 1281 + self.state = 1292 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -11612,21 +11649,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 = 1283 + self.state = 1294 if not self.precpred(self._ctx, 4): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") - self.state = 1285 + self.state = 1296 self._errHandler.sync(self) _la = self._input.LA(1) if _la==141: - self.state = 1284 + self.state = 1295 self.match(PartiQLParser.NOT) - self.state = 1287 + self.state = 1298 self.match(PartiQLParser.IN) - self.state = 1288 + self.state = 1299 localctx.rhs = self.mathOp00(0) pass @@ -11634,29 +11671,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 = 1289 + self.state = 1300 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 1291 + self.state = 1302 self._errHandler.sync(self) _la = self._input.LA(1) if _la==141: - self.state = 1290 + self.state = 1301 self.match(PartiQLParser.NOT) - self.state = 1293 + self.state = 1304 self.match(PartiQLParser.LIKE) - self.state = 1294 + self.state = 1305 localctx.rhs = self.mathOp00(0) - self.state = 1297 + self.state = 1308 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,165,self._ctx) if la_ == 1: - self.state = 1295 + self.state = 1306 self.match(PartiQLParser.ESCAPE) - self.state = 1296 + self.state = 1307 localctx.escape = self.expr() @@ -11666,30 +11703,30 @@ 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 = 1299 + self.state = 1310 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1301 + self.state = 1312 self._errHandler.sync(self) _la = self._input.LA(1) if _la==141: - self.state = 1300 + self.state = 1311 self.match(PartiQLParser.NOT) - self.state = 1303 + self.state = 1314 self.match(PartiQLParser.BETWEEN) - self.state = 1304 + self.state = 1315 localctx.lower = self.mathOp00(0) - self.state = 1305 + self.state = 1316 self.match(PartiQLParser.AND) - self.state = 1306 + self.state = 1317 localctx.upper = self.mathOp00(0) pass - self.state = 1312 + self.state = 1323 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,168,self._ctx) @@ -11756,10 +11793,10 @@ def mathOp00(self, _p:int=0): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1314 + self.state = 1325 localctx.parent_ = self.mathOp01(0) self._ctx.stop = self._input.LT(-1) - self.state = 1321 + self.state = 1332 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,169,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -11770,11 +11807,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 = 1316 + 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 = 1317 + self.state = 1328 localctx.op = self._input.LT(1) _la = self._input.LA(1) if not(_la==280 or _la==286): @@ -11782,9 +11819,9 @@ def mathOp00(self, _p:int=0): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1318 + self.state = 1329 localctx.rhs = self.mathOp01(0) - self.state = 1323 + self.state = 1334 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,169,self._ctx) @@ -11851,10 +11888,10 @@ def mathOp01(self, _p:int=0): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1325 + self.state = 1336 localctx.parent_ = self.mathOp02(0) self._ctx.stop = self._input.LT(-1) - self.state = 1332 + self.state = 1343 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,170,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -11865,11 +11902,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 = 1327 + 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 = 1328 + self.state = 1339 localctx.op = self._input.LT(1) _la = self._input.LA(1) if not(_la==272 or _la==273): @@ -11877,9 +11914,9 @@ def mathOp01(self, _p:int=0): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1329 + self.state = 1340 localctx.rhs = self.mathOp02(0) - self.state = 1334 + self.state = 1345 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,170,self._ctx) @@ -11949,10 +11986,10 @@ def mathOp02(self, _p:int=0): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1336 + self.state = 1347 localctx.parent_ = self.valueExpr() self._ctx.stop = self._input.LT(-1) - self.state = 1343 + self.state = 1354 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,171,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -11963,11 +12000,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 = 1338 + self.state = 1349 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 1339 + self.state = 1350 localctx.op = self._input.LT(1) _la = self._input.LA(1) if not(((((_la - 274)) & ~0x3f) == 0 and ((1 << (_la - 274)) & 19) != 0)): @@ -11975,9 +12012,9 @@ def mathOp02(self, _p:int=0): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1340 + self.state = 1351 localctx.rhs = self.valueExpr() - self.state = 1345 + self.state = 1356 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,171,self._ctx) @@ -12040,12 +12077,12 @@ def valueExpr(self): self.enterRule(localctx, 208, self.RULE_valueExpr) self._la = 0 # Token type try: - self.state = 1349 + self.state = 1360 self._errHandler.sync(self) token = self._input.LA(1) if token in [272, 273]: self.enterOuterAlt(localctx, 1) - self.state = 1346 + self.state = 1357 localctx.sign = self._input.LT(1) _la = self._input.LA(1) if not(_la==272 or _la==273): @@ -12053,12 +12090,12 @@ def valueExpr(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1347 + self.state = 1358 localctx.rhs = self.valueExpr() pass elif token in [8, 15, 19, 23, 24, 28, 29, 32, 44, 48, 51, 53, 54, 76, 80, 83, 86, 87, 88, 89, 130, 132, 133, 142, 144, 146, 157, 161, 174, 188, 190, 196, 197, 202, 203, 208, 209, 214, 220, 231, 232, 235, 236, 237, 267, 268, 276, 289, 291, 293, 295, 299, 301, 302, 303, 304, 305, 310]: self.enterOuterAlt(localctx, 2) - self.state = 1348 + self.state = 1359 localctx.parent_ = self.exprPrimary(0) pass else: @@ -12212,7 +12249,7 @@ def exprPrimary(self, _p:int=0): self.enterRecursionRule(localctx, 210, self.RULE_exprPrimary, _p) try: self.enterOuterAlt(localctx, 1) - self.state = 1372 + self.state = 1383 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,173,self._ctx) if la_ == 1: @@ -12220,7 +12257,7 @@ def exprPrimary(self, _p:int=0): self._ctx = localctx _prevctx = localctx - self.state = 1352 + self.state = 1363 self.exprTerm() pass @@ -12228,7 +12265,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1353 + self.state = 1364 self.cast() pass @@ -12236,7 +12273,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1354 + self.state = 1365 self.sequenceConstructor() pass @@ -12244,7 +12281,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1355 + self.state = 1366 self.substring() pass @@ -12252,7 +12289,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1356 + self.state = 1367 self.position() pass @@ -12260,7 +12297,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1357 + self.state = 1368 self.overlay() pass @@ -12268,7 +12305,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1358 + self.state = 1369 self.canCast() pass @@ -12276,7 +12313,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1359 + self.state = 1370 self.canLosslessCast() pass @@ -12284,7 +12321,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1360 + self.state = 1371 self.extract() pass @@ -12292,7 +12329,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1361 + self.state = 1372 self.coalesce() pass @@ -12300,7 +12337,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1362 + self.state = 1373 self.dateFunction() pass @@ -12308,7 +12345,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1363 + self.state = 1374 self.aggregate() pass @@ -12316,7 +12353,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1364 + self.state = 1375 self.trimFunction() pass @@ -12324,7 +12361,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1365 + self.state = 1376 self.functionCall() pass @@ -12332,7 +12369,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1366 + self.state = 1377 self.nullIf() pass @@ -12340,7 +12377,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1367 + self.state = 1378 self.exprGraphMatchMany() pass @@ -12348,7 +12385,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1368 + self.state = 1379 self.caseExpr() pass @@ -12356,7 +12393,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1369 + self.state = 1380 self.valueList() pass @@ -12364,7 +12401,7 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1370 + self.state = 1381 self.values() pass @@ -12372,13 +12409,13 @@ def exprPrimary(self, _p:int=0): localctx = PartiQLParser.ExprPrimaryBaseContext(self, localctx) self._ctx = localctx _prevctx = localctx - self.state = 1371 + self.state = 1382 self.windowFunction() pass self._ctx.stop = self._input.LT(-1) - self.state = 1382 + self.state = 1393 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,175,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -12388,25 +12425,25 @@ 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 = 1374 + self.state = 1385 if not self.precpred(self._ctx, 6): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 6)") - self.state = 1376 + self.state = 1387 self._errHandler.sync(self) _alt = 1 while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt == 1: - self.state = 1375 + self.state = 1386 self.pathStep() else: raise NoViableAltException(self) - self.state = 1378 + self.state = 1389 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,174,self._ctx) - self.state = 1384 + self.state = 1395 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,175,self._ctx) @@ -12556,59 +12593,59 @@ def exprTerm(self): localctx = PartiQLParser.ExprTermContext(self, self._ctx, self.state) self.enterRule(localctx, 212, self.RULE_exprTerm) try: - self.state = 1396 + self.state = 1407 self._errHandler.sync(self) token = self._input.LA(1) if token in [295]: localctx = PartiQLParser.ExprTermWrappedQueryContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1385 + self.state = 1396 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1386 + self.state = 1397 self.expr() - self.state = 1387 + self.state = 1398 self.match(PartiQLParser.PAREN_RIGHT) pass elif token in [51]: localctx = PartiQLParser.ExprTermCurrentUserContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1389 + self.state = 1400 self.match(PartiQLParser.CURRENT_USER) pass elif token in [48]: localctx = PartiQLParser.ExprTermCurrentDateContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1390 + self.state = 1401 self.match(PartiQLParser.CURRENT_DATE) pass elif token in [299]: localctx = PartiQLParser.ExprTermBaseContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 1391 + self.state = 1402 self.parameter() pass elif token in [80, 276, 304, 305]: localctx = PartiQLParser.ExprTermBaseContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 1392 + self.state = 1403 self.varRefExpr() pass elif token in [53, 89, 142, 202, 203, 209, 237, 301, 302, 303, 310]: localctx = PartiQLParser.ExprTermBaseContext(self, localctx) self.enterOuterAlt(localctx, 6) - self.state = 1393 + self.state = 1404 self.literal() pass elif token in [289, 291]: localctx = PartiQLParser.ExprTermBaseContext(self, localctx) self.enterOuterAlt(localctx, 7) - self.state = 1394 + self.state = 1405 self.collection() pass elif token in [293]: localctx = PartiQLParser.ExprTermBaseContext(self, localctx) self.enterOuterAlt(localctx, 8) - self.state = 1395 + self.state = 1406 self.tuple_() pass else: @@ -12675,17 +12712,17 @@ def nullIf(self): self.enterRule(localctx, 214, self.RULE_nullIf) try: self.enterOuterAlt(localctx, 1) - self.state = 1398 + self.state = 1409 self.match(PartiQLParser.NULLIF) - self.state = 1399 + self.state = 1410 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1400 + self.state = 1411 self.expr() - self.state = 1401 + self.state = 1412 self.match(PartiQLParser.COMMA) - self.state = 1402 + self.state = 1413 self.expr() - self.state = 1403 + self.state = 1414 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -12752,25 +12789,25 @@ def coalesce(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1405 + self.state = 1416 self.match(PartiQLParser.COALESCE) - self.state = 1406 + self.state = 1417 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1407 + self.state = 1418 self.expr() - self.state = 1412 + self.state = 1423 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 1408 + self.state = 1419 self.match(PartiQLParser.COMMA) - self.state = 1409 + self.state = 1420 self.expr() - self.state = 1414 + self.state = 1425 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1415 + self.state = 1426 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -12848,47 +12885,47 @@ def caseExpr(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1417 + self.state = 1428 self.match(PartiQLParser.CASE) - self.state = 1419 + self.state = 1430 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 29572469866660096) != 0) or ((((_la - 76)) & ~0x3f) == 0 and ((1 << (_la - 76)) & 234187180623281297) != 0) or ((((_la - 141)) & ~0x3f) == 0 and ((1 << (_la - 141)) & 7026323512777310251) != 0) or ((((_la - 208)) & ~0x3f) == 0 and ((1 << (_la - 208)) & 1729382258948706371) != 0) or ((((_la - 272)) & ~0x3f) == 0 and ((1 << (_la - 272)) & 291666264083) != 0): - self.state = 1418 + self.state = 1429 localctx.case = self.expr() - self.state = 1426 + self.state = 1437 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 1421 + self.state = 1432 self.match(PartiQLParser.WHEN) - self.state = 1422 + self.state = 1433 localctx._expr = self.expr() localctx.whens.append(localctx._expr) - self.state = 1423 + self.state = 1434 self.match(PartiQLParser.THEN) - self.state = 1424 + self.state = 1435 localctx._expr = self.expr() localctx.thens.append(localctx._expr) - self.state = 1428 + self.state = 1439 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==224): break - self.state = 1432 + self.state = 1443 self._errHandler.sync(self) _la = self._input.LA(1) if _la==72: - self.state = 1430 + self.state = 1441 self.match(PartiQLParser.ELSE) - self.state = 1431 + self.state = 1442 localctx.else_ = self.expr() - self.state = 1434 + self.state = 1445 self.match(PartiQLParser.END) except RecognitionException as re: localctx.exception = re @@ -12948,20 +12985,20 @@ def values(self): self.enterRule(localctx, 220, self.RULE_values) try: self.enterOuterAlt(localctx, 1) - self.state = 1436 + self.state = 1447 self.match(PartiQLParser.VALUES) - self.state = 1437 + self.state = 1448 self.valueRow() - self.state = 1442 + self.state = 1453 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,181,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 1438 + self.state = 1449 self.match(PartiQLParser.COMMA) - self.state = 1439 + self.state = 1450 self.valueRow() - self.state = 1444 + self.state = 1455 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,181,self._ctx) @@ -13027,23 +13064,23 @@ def valueRow(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1445 + self.state = 1456 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1446 + self.state = 1457 self.expr() - self.state = 1451 + self.state = 1462 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 1447 + self.state = 1458 self.match(PartiQLParser.COMMA) - self.state = 1448 + self.state = 1459 self.expr() - self.state = 1453 + self.state = 1464 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1454 + self.state = 1465 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -13107,25 +13144,25 @@ def valueList(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1456 + self.state = 1467 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1457 + self.state = 1468 self.expr() - self.state = 1460 + self.state = 1471 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 1458 + self.state = 1469 self.match(PartiQLParser.COMMA) - self.state = 1459 + self.state = 1470 self.expr() - self.state = 1462 + self.state = 1473 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==271): break - self.state = 1464 + self.state = 1475 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -13196,7 +13233,7 @@ def sequenceConstructor(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1466 + self.state = 1477 localctx.datatype = self._input.LT(1) _la = self._input.LA(1) if not(_la==267 or _la==268): @@ -13204,29 +13241,29 @@ def sequenceConstructor(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1467 + self.state = 1478 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1476 + self.state = 1487 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 29572469866660096) != 0) or ((((_la - 76)) & ~0x3f) == 0 and ((1 << (_la - 76)) & 234187180623281297) != 0) or ((((_la - 141)) & ~0x3f) == 0 and ((1 << (_la - 141)) & 7026323512777310251) != 0) or ((((_la - 208)) & ~0x3f) == 0 and ((1 << (_la - 208)) & 1729382258948706371) != 0) or ((((_la - 272)) & ~0x3f) == 0 and ((1 << (_la - 272)) & 291666264083) != 0): - self.state = 1468 + self.state = 1479 self.expr() - self.state = 1473 + self.state = 1484 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 1469 + self.state = 1480 self.match(PartiQLParser.COMMA) - self.state = 1470 + self.state = 1481 self.expr() - self.state = 1475 + self.state = 1486 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1478 + self.state = 1489 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -13298,70 +13335,70 @@ def substring(self): self.enterRule(localctx, 228, self.RULE_substring) self._la = 0 # Token type try: - self.state = 1506 + self.state = 1517 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,190,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 1480 + self.state = 1491 self.match(PartiQLParser.SUBSTRING) - self.state = 1481 + self.state = 1492 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1482 + self.state = 1493 self.expr() - self.state = 1489 + self.state = 1500 self._errHandler.sync(self) _la = self._input.LA(1) if _la==271: - self.state = 1483 + self.state = 1494 self.match(PartiQLParser.COMMA) - self.state = 1484 + self.state = 1495 self.expr() - self.state = 1487 + self.state = 1498 self._errHandler.sync(self) _la = self._input.LA(1) if _la==271: - self.state = 1485 + self.state = 1496 self.match(PartiQLParser.COMMA) - self.state = 1486 + self.state = 1497 self.expr() - self.state = 1491 + self.state = 1502 self.match(PartiQLParser.PAREN_RIGHT) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 1493 + self.state = 1504 self.match(PartiQLParser.SUBSTRING) - self.state = 1494 + self.state = 1505 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1495 + self.state = 1506 self.expr() - self.state = 1502 + self.state = 1513 self._errHandler.sync(self) _la = self._input.LA(1) if _la==96: - self.state = 1496 + self.state = 1507 self.match(PartiQLParser.FROM) - self.state = 1497 + self.state = 1508 self.expr() - self.state = 1500 + self.state = 1511 self._errHandler.sync(self) _la = self._input.LA(1) if _la==93: - self.state = 1498 + self.state = 1509 self.match(PartiQLParser.FOR) - self.state = 1499 + self.state = 1510 self.expr() - self.state = 1504 + self.state = 1515 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -13429,38 +13466,38 @@ def position(self): localctx = PartiQLParser.PositionContext(self, self._ctx, self.state) self.enterRule(localctx, 230, self.RULE_position) try: - self.state = 1522 + self.state = 1533 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,191,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 1508 + self.state = 1519 self.match(PartiQLParser.POSITION) - self.state = 1509 + self.state = 1520 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1510 + self.state = 1521 self.expr() - self.state = 1511 + self.state = 1522 self.match(PartiQLParser.COMMA) - self.state = 1512 + self.state = 1523 self.expr() - self.state = 1513 + self.state = 1524 self.match(PartiQLParser.PAREN_RIGHT) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 1515 + self.state = 1526 self.match(PartiQLParser.POSITION) - self.state = 1516 + self.state = 1527 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1517 + self.state = 1528 self.expr() - self.state = 1518 + self.state = 1529 self.match(PartiQLParser.IN) - self.state = 1519 + self.state = 1530 self.expr() - self.state = 1520 + self.state = 1531 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -13538,66 +13575,66 @@ def overlay(self): self.enterRule(localctx, 232, self.RULE_overlay) self._la = 0 # Token type try: - self.state = 1550 + self.state = 1561 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,194,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 1524 + self.state = 1535 self.match(PartiQLParser.OVERLAY) - self.state = 1525 + self.state = 1536 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1526 + self.state = 1537 self.expr() - self.state = 1527 + self.state = 1538 self.match(PartiQLParser.COMMA) - self.state = 1528 + self.state = 1539 self.expr() - self.state = 1529 + self.state = 1540 self.match(PartiQLParser.COMMA) - self.state = 1530 + self.state = 1541 self.expr() - self.state = 1533 + self.state = 1544 self._errHandler.sync(self) _la = self._input.LA(1) if _la==271: - self.state = 1531 + self.state = 1542 self.match(PartiQLParser.COMMA) - self.state = 1532 + self.state = 1543 self.expr() - self.state = 1535 + self.state = 1546 self.match(PartiQLParser.PAREN_RIGHT) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 1537 + self.state = 1548 self.match(PartiQLParser.OVERLAY) - self.state = 1538 + self.state = 1549 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1539 + self.state = 1550 self.expr() - self.state = 1540 + self.state = 1551 self.match(PartiQLParser.PLACING) - self.state = 1541 + self.state = 1552 self.expr() - self.state = 1542 + self.state = 1553 self.match(PartiQLParser.FROM) - self.state = 1543 + self.state = 1554 self.expr() - self.state = 1546 + self.state = 1557 self._errHandler.sync(self) _la = self._input.LA(1) if _la==93: - self.state = 1544 + self.state = 1555 self.match(PartiQLParser.FOR) - self.state = 1545 + self.state = 1556 self.expr() - self.state = 1548 + self.state = 1559 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -13715,26 +13752,26 @@ def aggregate(self): self.enterRule(localctx, 234, self.RULE_aggregate) self._la = 0 # Token type try: - self.state = 1564 + self.state = 1575 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,196,self._ctx) if la_ == 1: localctx = PartiQLParser.CountAllContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1552 + self.state = 1563 localctx.func = self.match(PartiQLParser.COUNT) - self.state = 1553 + self.state = 1564 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1554 + self.state = 1565 self.match(PartiQLParser.ASTERISK) - self.state = 1555 + self.state = 1566 self.match(PartiQLParser.PAREN_RIGHT) pass elif la_ == 2: localctx = PartiQLParser.AggregateBaseContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1556 + self.state = 1567 localctx.func = self._input.LT(1) _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 17592186077440) != 0) or ((((_la - 76)) & ~0x3f) == 0 and ((1 << (_la - 76)) & 216172782113783809) != 0) or _la==190 or _la==197): @@ -13742,19 +13779,19 @@ def aggregate(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1557 + self.state = 1568 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1559 + self.state = 1570 self._errHandler.sync(self) _la = self._input.LA(1) if _la==4 or _la==68: - self.state = 1558 + self.state = 1569 self.setQuantifierStrategy() - self.state = 1561 + self.state = 1572 self.expr() - self.state = 1562 + self.state = 1573 self.match(PartiQLParser.PAREN_RIGHT) pass @@ -13839,7 +13876,7 @@ def windowFunction(self): try: localctx = PartiQLParser.LagLeadFunctionContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1566 + self.state = 1577 localctx.func = self._input.LT(1) _la = self._input.LA(1) if not(_la==231 or _la==232): @@ -13847,33 +13884,33 @@ def windowFunction(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1567 + self.state = 1578 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1568 + self.state = 1579 self.expr() - self.state = 1575 + self.state = 1586 self._errHandler.sync(self) _la = self._input.LA(1) if _la==271: - self.state = 1569 + self.state = 1580 self.match(PartiQLParser.COMMA) - self.state = 1570 + self.state = 1581 self.expr() - self.state = 1573 + self.state = 1584 self._errHandler.sync(self) _la = self._input.LA(1) if _la==271: - self.state = 1571 + self.state = 1582 self.match(PartiQLParser.COMMA) - self.state = 1572 + self.state = 1583 self.expr() - self.state = 1577 + self.state = 1588 self.match(PartiQLParser.PAREN_RIGHT) - self.state = 1578 + self.state = 1589 self.over() except RecognitionException as re: localctx.exception = re @@ -13937,17 +13974,17 @@ def cast(self): self.enterRule(localctx, 238, self.RULE_cast) try: self.enterOuterAlt(localctx, 1) - self.state = 1580 + self.state = 1591 self.match(PartiQLParser.CAST) - self.state = 1581 + self.state = 1592 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1582 + self.state = 1593 self.expr() - self.state = 1583 + self.state = 1594 self.match(PartiQLParser.AS) - self.state = 1584 + self.state = 1595 self.type_() - self.state = 1585 + self.state = 1596 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14011,17 +14048,17 @@ def canLosslessCast(self): self.enterRule(localctx, 240, self.RULE_canLosslessCast) try: self.enterOuterAlt(localctx, 1) - self.state = 1587 + self.state = 1598 self.match(PartiQLParser.CAN_LOSSLESS_CAST) - self.state = 1588 + self.state = 1599 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1589 + self.state = 1600 self.expr() - self.state = 1590 + self.state = 1601 self.match(PartiQLParser.AS) - self.state = 1591 + self.state = 1602 self.type_() - self.state = 1592 + self.state = 1603 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14085,17 +14122,17 @@ def canCast(self): self.enterRule(localctx, 242, self.RULE_canCast) try: self.enterOuterAlt(localctx, 1) - self.state = 1594 + self.state = 1605 self.match(PartiQLParser.CAN_CAST) - self.state = 1595 + self.state = 1606 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1596 + self.state = 1607 self.expr() - self.state = 1597 + self.state = 1608 self.match(PartiQLParser.AS) - self.state = 1598 + self.state = 1609 self.type_() - self.state = 1599 + self.state = 1610 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14159,17 +14196,17 @@ def extract(self): self.enterRule(localctx, 244, self.RULE_extract) try: self.enterOuterAlt(localctx, 1) - self.state = 1601 + self.state = 1612 self.match(PartiQLParser.EXTRACT) - self.state = 1602 + self.state = 1613 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1603 + self.state = 1614 self.match(PartiQLParser.IDENTIFIER) - self.state = 1604 + self.state = 1615 self.match(PartiQLParser.FROM) - self.state = 1605 + self.state = 1616 localctx.rhs = self.expr() - self.state = 1606 + self.state = 1617 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14240,37 +14277,37 @@ def trimFunction(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1608 + self.state = 1619 localctx.func = self.match(PartiQLParser.TRIM) - self.state = 1609 + self.state = 1620 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1617 + self.state = 1628 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,201,self._ctx) if la_ == 1: - self.state = 1611 + self.state = 1622 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,199,self._ctx) if la_ == 1: - self.state = 1610 + self.state = 1621 localctx.mod = self.match(PartiQLParser.IDENTIFIER) - self.state = 1614 + self.state = 1625 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 29572469866660096) != 0) or ((((_la - 76)) & ~0x3f) == 0 and ((1 << (_la - 76)) & 234187180623281297) != 0) or ((((_la - 141)) & ~0x3f) == 0 and ((1 << (_la - 141)) & 7026323512777310251) != 0) or ((((_la - 208)) & ~0x3f) == 0 and ((1 << (_la - 208)) & 1729382258948706371) != 0) or ((((_la - 272)) & ~0x3f) == 0 and ((1 << (_la - 272)) & 291666264083) != 0): - self.state = 1613 + self.state = 1624 localctx.sub = self.expr() - self.state = 1616 + self.state = 1627 self.match(PartiQLParser.FROM) - self.state = 1619 + self.state = 1630 localctx.target = self.expr() - self.state = 1620 + self.state = 1631 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14345,7 +14382,7 @@ def dateFunction(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1622 + self.state = 1633 localctx.func = self._input.LT(1) _la = self._input.LA(1) if not(_la==87 or _la==88): @@ -14353,19 +14390,19 @@ def dateFunction(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1623 + self.state = 1634 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1624 + self.state = 1635 localctx.dt = self.match(PartiQLParser.IDENTIFIER) - self.state = 1625 + self.state = 1636 self.match(PartiQLParser.COMMA) - self.state = 1626 + self.state = 1637 self.expr() - self.state = 1627 + self.state = 1638 self.match(PartiQLParser.COMMA) - self.state = 1628 + self.state = 1639 self.expr() - self.state = 1629 + self.state = 1640 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14433,31 +14470,31 @@ def functionCall(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1631 + self.state = 1642 self.functionName() - self.state = 1632 + self.state = 1643 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1641 + self.state = 1652 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 29572469866660096) != 0) or ((((_la - 76)) & ~0x3f) == 0 and ((1 << (_la - 76)) & 234187180623281297) != 0) or ((((_la - 141)) & ~0x3f) == 0 and ((1 << (_la - 141)) & 7026323512777310251) != 0) or ((((_la - 208)) & ~0x3f) == 0 and ((1 << (_la - 208)) & 1729382258948706371) != 0) or ((((_la - 272)) & ~0x3f) == 0 and ((1 << (_la - 272)) & 291666264083) != 0): - self.state = 1633 + self.state = 1644 self.expr() - self.state = 1638 + self.state = 1649 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 1634 + self.state = 1645 self.match(PartiQLParser.COMMA) - self.state = 1635 + self.state = 1646 self.expr() - self.state = 1640 + self.state = 1651 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1643 + self.state = 1654 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14592,26 +14629,26 @@ def functionName(self): self.enterRule(localctx, 252, self.RULE_functionName) self._la = 0 # Token type try: - self.state = 1663 + self.state = 1674 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,206,self._ctx) if la_ == 1: localctx = PartiQLParser.FunctionNameReservedContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1650 + self.state = 1661 self._errHandler.sync(self) _la = self._input.LA(1) while _la==304 or _la==305: - self.state = 1645 + self.state = 1656 localctx._symbolPrimitive = self.symbolPrimitive() localctx.qualifier.append(localctx._symbolPrimitive) - self.state = 1646 + self.state = 1657 self.match(PartiQLParser.PERIOD) - self.state = 1652 + self.state = 1663 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1653 + self.state = 1664 localctx.name = self._input.LT(1) _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 27039190756098048) != 0) or ((((_la - 83)) & ~0x3f) == 0 and ((1 << (_la - 83)) & -9223231299366420479) != 0) or ((((_la - 174)) & ~0x3f) == 0 and ((1 << (_la - 174)) & 1116695707649) != 0)): @@ -14624,21 +14661,21 @@ def functionName(self): elif la_ == 2: localctx = PartiQLParser.FunctionNameSymbolContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1659 + self.state = 1670 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,205,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 1654 + self.state = 1665 localctx._symbolPrimitive = self.symbolPrimitive() localctx.qualifier.append(localctx._symbolPrimitive) - self.state = 1655 + self.state = 1666 self.match(PartiQLParser.PERIOD) - self.state = 1661 + self.state = 1672 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,205,self._ctx) - self.state = 1662 + self.state = 1673 localctx.name = self.symbolPrimitive() pass @@ -14789,46 +14826,46 @@ def pathStep(self): localctx = PartiQLParser.PathStepContext(self, self._ctx, self.state) self.enterRule(localctx, 254, self.RULE_pathStep) try: - self.state = 1676 + self.state = 1687 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,207,self._ctx) if la_ == 1: localctx = PartiQLParser.PathStepIndexExprContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1665 + self.state = 1676 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 1666 + self.state = 1677 localctx.key = self.expr() - self.state = 1667 + self.state = 1678 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 2: localctx = PartiQLParser.PathStepIndexAllContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1669 + self.state = 1680 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 1670 + self.state = 1681 localctx.all_ = self.match(PartiQLParser.ASTERISK) - self.state = 1671 + self.state = 1682 self.match(PartiQLParser.BRACKET_RIGHT) pass elif la_ == 3: localctx = PartiQLParser.PathStepDotExprContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1672 + self.state = 1683 self.match(PartiQLParser.PERIOD) - self.state = 1673 + self.state = 1684 localctx.key = self.symbolPrimitive() pass elif la_ == 4: localctx = PartiQLParser.PathStepDotAllContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 1674 + self.state = 1685 self.match(PartiQLParser.PERIOD) - self.state = 1675 + self.state = 1686 localctx.all_ = self.match(PartiQLParser.ASTERISK) pass @@ -14892,15 +14929,15 @@ def exprGraphMatchMany(self): self.enterRule(localctx, 256, self.RULE_exprGraphMatchMany) try: self.enterOuterAlt(localctx, 1) - self.state = 1678 + self.state = 1689 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1679 + self.state = 1690 self.exprPrimary(0) - self.state = 1680 + self.state = 1691 self.match(PartiQLParser.MATCH) - self.state = 1681 + self.state = 1692 self.gpmlPatternList() - self.state = 1682 + self.state = 1693 self.match(PartiQLParser.PAREN_RIGHT) except RecognitionException as re: localctx.exception = re @@ -14955,11 +14992,11 @@ def exprGraphMatchOne(self): self.enterRule(localctx, 258, self.RULE_exprGraphMatchOne) try: self.enterOuterAlt(localctx, 1) - self.state = 1684 + self.state = 1695 self.exprPrimary(0) - self.state = 1685 + self.state = 1696 self.match(PartiQLParser.MATCH) - self.state = 1686 + self.state = 1697 self.gpmlPattern() except RecognitionException as re: localctx.exception = re @@ -15006,7 +15043,7 @@ def parameter(self): self.enterRule(localctx, 260, self.RULE_parameter) try: self.enterOuterAlt(localctx, 1) - self.state = 1688 + self.state = 1699 self.match(PartiQLParser.QUESTION_MARK) except RecognitionException as re: localctx.exception = re @@ -15100,21 +15137,21 @@ def varRefExpr(self): self.enterRule(localctx, 262, self.RULE_varRefExpr) self._la = 0 # Token type try: - self.state = 1698 + self.state = 1709 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,210,self._ctx) if la_ == 1: localctx = PartiQLParser.VariableIdentifierContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1691 + self.state = 1702 self._errHandler.sync(self) _la = self._input.LA(1) if _la==276: - self.state = 1690 + self.state = 1701 localctx.qualifier = self.match(PartiQLParser.AT_SIGN) - self.state = 1693 + self.state = 1704 localctx.ident = self._input.LT(1) _la = self._input.LA(1) if not(_la==304 or _la==305): @@ -15127,15 +15164,15 @@ def varRefExpr(self): elif la_ == 2: localctx = PartiQLParser.VariableKeywordContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1695 + self.state = 1706 self._errHandler.sync(self) _la = self._input.LA(1) if _la==276: - self.state = 1694 + self.state = 1705 localctx.qualifier = self.match(PartiQLParser.AT_SIGN) - self.state = 1697 + self.state = 1708 localctx.key = self.nonReservedKeywords() pass @@ -15185,7 +15222,7 @@ def nonReservedKeywords(self): self.enterRule(localctx, 264, self.RULE_nonReservedKeywords) try: self.enterOuterAlt(localctx, 1) - self.state = 1700 + self.state = 1711 self.match(PartiQLParser.EXCLUDED) except RecognitionException as re: localctx.exception = re @@ -15236,17 +15273,17 @@ def collection(self): localctx = PartiQLParser.CollectionContext(self, self._ctx, self.state) self.enterRule(localctx, 266, self.RULE_collection) try: - self.state = 1704 + self.state = 1715 self._errHandler.sync(self) token = self._input.LA(1) if token in [291]: self.enterOuterAlt(localctx, 1) - self.state = 1702 + self.state = 1713 self.array() pass elif token in [289]: self.enterOuterAlt(localctx, 2) - self.state = 1703 + self.state = 1714 self.bag() pass else: @@ -15314,29 +15351,29 @@ def array(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1706 + self.state = 1717 self.match(PartiQLParser.BRACKET_LEFT) - self.state = 1715 + self.state = 1726 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 29572469866660096) != 0) or ((((_la - 76)) & ~0x3f) == 0 and ((1 << (_la - 76)) & 234187180623281297) != 0) or ((((_la - 141)) & ~0x3f) == 0 and ((1 << (_la - 141)) & 7026323512777310251) != 0) or ((((_la - 208)) & ~0x3f) == 0 and ((1 << (_la - 208)) & 1729382258948706371) != 0) or ((((_la - 272)) & ~0x3f) == 0 and ((1 << (_la - 272)) & 291666264083) != 0): - self.state = 1707 + self.state = 1718 self.expr() - self.state = 1712 + self.state = 1723 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 1708 + self.state = 1719 self.match(PartiQLParser.COMMA) - self.state = 1709 + self.state = 1720 self.expr() - self.state = 1714 + self.state = 1725 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1717 + self.state = 1728 self.match(PartiQLParser.BRACKET_RIGHT) except RecognitionException as re: localctx.exception = re @@ -15400,29 +15437,29 @@ def bag(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1719 + self.state = 1730 self.match(PartiQLParser.ANGLE_DOUBLE_LEFT) - self.state = 1728 + self.state = 1739 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 29572469866660096) != 0) or ((((_la - 76)) & ~0x3f) == 0 and ((1 << (_la - 76)) & 234187180623281297) != 0) or ((((_la - 141)) & ~0x3f) == 0 and ((1 << (_la - 141)) & 7026323512777310251) != 0) or ((((_la - 208)) & ~0x3f) == 0 and ((1 << (_la - 208)) & 1729382258948706371) != 0) or ((((_la - 272)) & ~0x3f) == 0 and ((1 << (_la - 272)) & 291666264083) != 0): - self.state = 1720 + self.state = 1731 self.expr() - self.state = 1725 + self.state = 1736 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 1721 + self.state = 1732 self.match(PartiQLParser.COMMA) - self.state = 1722 + self.state = 1733 self.expr() - self.state = 1727 + self.state = 1738 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1730 + self.state = 1741 self.match(PartiQLParser.ANGLE_DOUBLE_RIGHT) except RecognitionException as re: localctx.exception = re @@ -15486,29 +15523,29 @@ def tuple_(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 1732 + self.state = 1743 self.match(PartiQLParser.BRACE_LEFT) - self.state = 1741 + self.state = 1752 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & 29572469866660096) != 0) or ((((_la - 76)) & ~0x3f) == 0 and ((1 << (_la - 76)) & 234187180623281297) != 0) or ((((_la - 141)) & ~0x3f) == 0 and ((1 << (_la - 141)) & 7026323512777310251) != 0) or ((((_la - 208)) & ~0x3f) == 0 and ((1 << (_la - 208)) & 1729382258948706371) != 0) or ((((_la - 272)) & ~0x3f) == 0 and ((1 << (_la - 272)) & 291666264083) != 0): - self.state = 1733 + self.state = 1744 self.pair() - self.state = 1738 + self.state = 1749 self._errHandler.sync(self) _la = self._input.LA(1) while _la==271: - self.state = 1734 + self.state = 1745 self.match(PartiQLParser.COMMA) - self.state = 1735 + self.state = 1746 self.pair() - self.state = 1740 + self.state = 1751 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 1743 + self.state = 1754 self.match(PartiQLParser.BRACE_RIGHT) except RecognitionException as re: localctx.exception = re @@ -15564,11 +15601,11 @@ def pair(self): self.enterRule(localctx, 274, self.RULE_pair) try: self.enterOuterAlt(localctx, 1) - self.state = 1745 + self.state = 1756 localctx.lhs = self.expr() - self.state = 1746 + self.state = 1757 self.match(PartiQLParser.COLON) - self.state = 1747 + self.state = 1758 localctx.rhs = self.expr() except RecognitionException as re: localctx.exception = re @@ -15898,127 +15935,127 @@ def literal(self): self.enterRule(localctx, 276, self.RULE_literal) self._la = 0 # Token type try: - self.state = 1783 + self.state = 1794 self._errHandler.sync(self) token = self._input.LA(1) if token in [142]: localctx = PartiQLParser.LiteralNullContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1749 + self.state = 1760 self.match(PartiQLParser.NULL) pass elif token in [237]: localctx = PartiQLParser.LiteralMissingContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1750 + self.state = 1761 self.match(PartiQLParser.MISSING) pass elif token in [209]: localctx = PartiQLParser.LiteralTrueContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1751 + self.state = 1762 self.match(PartiQLParser.TRUE) pass elif token in [89]: localctx = PartiQLParser.LiteralFalseContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 1752 + self.state = 1763 self.match(PartiQLParser.FALSE) pass elif token in [301]: localctx = PartiQLParser.LiteralStringContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 1753 + self.state = 1764 self.match(PartiQLParser.LITERAL_STRING) pass elif token in [302]: localctx = PartiQLParser.LiteralIntegerContext(self, localctx) self.enterOuterAlt(localctx, 6) - self.state = 1754 + self.state = 1765 self.match(PartiQLParser.LITERAL_INTEGER) pass elif token in [303]: localctx = PartiQLParser.LiteralDecimalContext(self, localctx) self.enterOuterAlt(localctx, 7) - self.state = 1755 + self.state = 1766 self.match(PartiQLParser.LITERAL_DECIMAL) pass elif token in [310]: localctx = PartiQLParser.LiteralIonContext(self, localctx) self.enterOuterAlt(localctx, 8) - self.state = 1756 + self.state = 1767 self.match(PartiQLParser.ION_CLOSURE) pass elif token in [53]: localctx = PartiQLParser.LiteralDateContext(self, localctx) self.enterOuterAlt(localctx, 9) - self.state = 1757 + self.state = 1768 self.match(PartiQLParser.DATE) - self.state = 1758 + self.state = 1769 self.match(PartiQLParser.LITERAL_STRING) pass elif token in [202]: localctx = PartiQLParser.LiteralTimeContext(self, localctx) self.enterOuterAlt(localctx, 10) - self.state = 1759 + self.state = 1770 self.match(PartiQLParser.TIME) - self.state = 1763 + self.state = 1774 self._errHandler.sync(self) _la = self._input.LA(1) if _la==295: - self.state = 1760 + self.state = 1771 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1761 + self.state = 1772 self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1762 + self.state = 1773 self.match(PartiQLParser.PAREN_RIGHT) - self.state = 1768 + self.state = 1779 self._errHandler.sync(self) _la = self._input.LA(1) if _la==227: - self.state = 1765 + self.state = 1776 self.match(PartiQLParser.WITH) - self.state = 1766 + self.state = 1777 self.match(PartiQLParser.TIME) - self.state = 1767 + self.state = 1778 self.match(PartiQLParser.ZONE) - self.state = 1770 + self.state = 1781 self.match(PartiQLParser.LITERAL_STRING) pass elif token in [203]: localctx = PartiQLParser.LiteralTimestampContext(self, localctx) self.enterOuterAlt(localctx, 11) - self.state = 1771 + self.state = 1782 self.match(PartiQLParser.TIMESTAMP) - self.state = 1775 + self.state = 1786 self._errHandler.sync(self) _la = self._input.LA(1) if _la==295: - self.state = 1772 + self.state = 1783 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1773 + self.state = 1784 self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1774 + self.state = 1785 self.match(PartiQLParser.PAREN_RIGHT) - self.state = 1780 + self.state = 1791 self._errHandler.sync(self) _la = self._input.LA(1) if _la==227: - self.state = 1777 + self.state = 1788 self.match(PartiQLParser.WITH) - self.state = 1778 + self.state = 1789 self.match(PartiQLParser.TIME) - self.state = 1779 + self.state = 1790 self.match(PartiQLParser.ZONE) - self.state = 1782 + self.state = 1793 self.match(PartiQLParser.LITERAL_STRING) pass else: @@ -16319,13 +16356,13 @@ def type_(self): self.enterRule(localctx, 278, self.RULE_type) self._la = 0 # Token type try: - self.state = 1823 + self.state = 1834 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,229,self._ctx) if la_ == 1: localctx = PartiQLParser.TypeAtomicContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 1785 + self.state = 1796 localctx.datatype = self._input.LT(1) _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 9007199456067840) != 0) or ((((_la - 114)) & ~0x3f) == 0 and ((1 << (_la - 114)) & 144115188344291331) != 0) or ((((_la - 189)) & ~0x3f) == 0 and ((1 << (_la - 189)) & -9223090561878065151) != 0) or ((((_la - 253)) & ~0x3f) == 0 and ((1 << (_la - 253)) & 131071) != 0)): @@ -16338,16 +16375,16 @@ def type_(self): elif la_ == 2: localctx = PartiQLParser.TypeAtomicContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 1786 + self.state = 1797 localctx.datatype = self.match(PartiQLParser.DOUBLE) - self.state = 1787 + self.state = 1798 self.match(PartiQLParser.PRECISION) pass elif la_ == 3: localctx = PartiQLParser.TypeArgSingleContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 1788 + self.state = 1799 localctx.datatype = self._input.LT(1) _la = self._input.LA(1) if not(_la==26 or _la==27 or _la==92 or _la==221): @@ -16355,15 +16392,15 @@ def type_(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1792 + self.state = 1803 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,223,self._ctx) if la_ == 1: - self.state = 1789 + self.state = 1800 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1790 + self.state = 1801 localctx.arg0 = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1791 + self.state = 1802 self.match(PartiQLParser.PAREN_RIGHT) @@ -16372,19 +16409,19 @@ def type_(self): elif la_ == 4: localctx = PartiQLParser.TypeVarCharContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 1794 + self.state = 1805 self.match(PartiQLParser.CHARACTER) - self.state = 1795 + self.state = 1806 self.match(PartiQLParser.VARYING) - self.state = 1799 + self.state = 1810 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,224,self._ctx) if la_ == 1: - self.state = 1796 + self.state = 1807 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1797 + self.state = 1808 localctx.arg0 = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1798 + self.state = 1809 self.match(PartiQLParser.PAREN_RIGHT) @@ -16393,7 +16430,7 @@ def type_(self): elif la_ == 5: localctx = PartiQLParser.TypeArgDoubleContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 1801 + self.state = 1812 localctx.datatype = self._input.LT(1) _la = self._input.LA(1) if not(_la==56 or _la==57 or _la==145): @@ -16401,25 +16438,25 @@ def type_(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1809 + self.state = 1820 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,226,self._ctx) if la_ == 1: - self.state = 1802 + self.state = 1813 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1803 + self.state = 1814 localctx.arg0 = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1806 + self.state = 1817 self._errHandler.sync(self) _la = self._input.LA(1) if _la==271: - self.state = 1804 + self.state = 1815 self.match(PartiQLParser.COMMA) - self.state = 1805 + self.state = 1816 localctx.arg1 = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1808 + self.state = 1819 self.match(PartiQLParser.PAREN_RIGHT) @@ -16428,7 +16465,7 @@ def type_(self): elif la_ == 6: localctx = PartiQLParser.TypeTimeZoneContext(self, localctx) self.enterOuterAlt(localctx, 6) - self.state = 1811 + self.state = 1822 localctx.datatype = self._input.LT(1) _la = self._input.LA(1) if not(_la==202 or _la==203): @@ -16436,27 +16473,27 @@ def type_(self): else: self._errHandler.reportMatch(self) self.consume() - self.state = 1815 + self.state = 1826 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,227,self._ctx) if la_ == 1: - self.state = 1812 + self.state = 1823 self.match(PartiQLParser.PAREN_LEFT) - self.state = 1813 + self.state = 1824 localctx.precision = self.match(PartiQLParser.LITERAL_INTEGER) - self.state = 1814 + self.state = 1825 self.match(PartiQLParser.PAREN_RIGHT) - self.state = 1820 + self.state = 1831 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,228,self._ctx) if la_ == 1: - self.state = 1817 + self.state = 1828 self.match(PartiQLParser.WITH) - self.state = 1818 + self.state = 1829 self.match(PartiQLParser.TIME) - self.state = 1819 + self.state = 1830 self.match(PartiQLParser.ZONE) @@ -16465,7 +16502,7 @@ def type_(self): elif la_ == 7: localctx = PartiQLParser.TypeCustomContext(self, localctx) self.enterOuterAlt(localctx, 7) - self.state = 1822 + self.state = 1833 self.symbolPrimitive() pass diff --git a/pymongosql/sql/partiql/PartiQLParserListener.py b/pymongosql/sql/partiql/PartiQLParserListener.py index c227691..e730375 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.1 +# Generated from PartiQLParser.g4 by ANTLR 4.13.2 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 b7ab7dd..e6a9e51 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.1 +# Generated from PartiQLParser.g4 by ANTLR 4.13.2 from antlr4 import * if "." in __name__: from .PartiQLParser import PartiQLParser