From f58635135ca4165db8439fb9347eb5cb52947efc Mon Sep 17 00:00:00 2001 From: Florent Poinsard <35779988+frouioui@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:04:13 -0600 Subject: [PATCH 01/40] Add `release-20.0` to the list of branches to upgrade the Go version on (#16053) Signed-off-by: Florent Poinsard --- .github/workflows/update_golang_version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update_golang_version.yml b/.github/workflows/update_golang_version.yml index c8f517eba48..f44458c63d8 100644 --- a/.github/workflows/update_golang_version.yml +++ b/.github/workflows/update_golang_version.yml @@ -15,7 +15,7 @@ jobs: pull-requests: write strategy: matrix: - branch: [ main, release-19.0, release-18.0, release-17.0, release-16.0 ] + branch: [ main, release-20.0, release-19.0, release-18.0, release-17.0 ] name: Update Golang Version runs-on: ubuntu-latest steps: From 79485f0f774c5db7dfad87fbc2d1d9e3c2d99b1e Mon Sep 17 00:00:00 2001 From: Florent Poinsard <35779988+frouioui@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:17:58 -0600 Subject: [PATCH 02/40] Add DCO workflow (#16052) Signed-off-by: Florent Poinsard --- .github/workflows/dco.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/dco.yml diff --git a/.github/workflows/dco.yml b/.github/workflows/dco.yml new file mode 100644 index 00000000000..eb377b4dd42 --- /dev/null +++ b/.github/workflows/dco.yml @@ -0,0 +1,24 @@ +name: DCO +on: + pull_request: + push: + branches: + - main + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Python 3.x + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Check DCO + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + pip3 install -U dco-check + dco-check --verbose \ No newline at end of file From 0a905e195a0d9a5afca205758487cf248014a761 Mon Sep 17 00:00:00 2001 From: vitess-bot <139342327+vitess-bot@users.noreply.github.com> Date: Tue, 4 Jun 2024 21:41:47 -0600 Subject: [PATCH 03/40] [main] Upgrade the Golang version to `go1.22.4` (#16062) Signed-off-by: GitHub Signed-off-by: Florent Poinsard Co-authored-by: frouioui Co-authored-by: Florent Poinsard --- .github/workflows/assign_milestone.yml | 2 +- .github/workflows/check_make_vtadmin_authz_testgen.yml | 2 +- .github/workflows/check_make_vtadmin_web_proto.yml | 2 +- .github/workflows/cluster_endtoend_12.yml | 2 +- .github/workflows/cluster_endtoend_13.yml | 2 +- .github/workflows/cluster_endtoend_15.yml | 2 +- .github/workflows/cluster_endtoend_18.yml | 2 +- .github/workflows/cluster_endtoend_21.yml | 2 +- .github/workflows/cluster_endtoend_22.yml | 2 +- .github/workflows/cluster_endtoend_backup_pitr.yml | 2 +- .../workflows/cluster_endtoend_backup_pitr_xtrabackup.yml | 2 +- .../cluster_endtoend_ers_prs_newfeatures_heavy.yml | 2 +- .github/workflows/cluster_endtoend_mysql80.yml | 2 +- .github/workflows/cluster_endtoend_mysql_server_vault.yml | 2 +- .github/workflows/cluster_endtoend_onlineddl_revert.yml | 2 +- .github/workflows/cluster_endtoend_onlineddl_scheduler.yml | 2 +- .github/workflows/cluster_endtoend_onlineddl_vrepl.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_vrepl_stress.yml | 2 +- .../cluster_endtoend_onlineddl_vrepl_stress_suite.yml | 2 +- .../workflows/cluster_endtoend_onlineddl_vrepl_suite.yml | 2 +- .github/workflows/cluster_endtoend_schemadiff_vrepl.yml | 2 +- .github/workflows/cluster_endtoend_tabletmanager_consul.yml | 2 +- .../workflows/cluster_endtoend_tabletmanager_tablegc.yml | 2 +- .../cluster_endtoend_tabletmanager_throttler_topo.yml | 2 +- .../workflows/cluster_endtoend_topo_connection_cache.yml | 2 +- .../cluster_endtoend_vreplication_across_db_versions.yml | 2 +- .github/workflows/cluster_endtoend_vreplication_basic.yml | 2 +- .../workflows/cluster_endtoend_vreplication_cellalias.yml | 2 +- .../cluster_endtoend_vreplication_copy_parallel.yml | 2 +- .../cluster_endtoend_vreplication_foreign_key_stress.yml | 2 +- .../cluster_endtoend_vreplication_mariadb_to_mysql.yml | 2 +- ...ster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml | 2 +- .../cluster_endtoend_vreplication_multi_tenant.yml | 2 +- ...oend_vreplication_partial_movetables_and_materialize.yml | 2 +- .github/workflows/cluster_endtoend_vreplication_v2.yml | 2 +- .github/workflows/cluster_endtoend_vstream.yml | 2 +- .github/workflows/cluster_endtoend_vtbackup.yml | 2 +- ...uster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_concurrentdml.yml | 2 +- .../workflows/cluster_endtoend_vtgate_foreignkey_stress.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_gen4.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_general_heavy.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_godriver.yml | 2 +- .../workflows/cluster_endtoend_vtgate_partial_keyspace.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_queries.yml | 2 +- .../workflows/cluster_endtoend_vtgate_readafterwrite.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_reservedconn.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_schema.yml | 2 +- .../workflows/cluster_endtoend_vtgate_schema_tracker.yml | 2 +- .../cluster_endtoend_vtgate_tablet_healthcheck_cache.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_topo.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_topo_consul.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_topo_etcd.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_transaction.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_unsharded.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml | 2 +- .github/workflows/cluster_endtoend_vtgate_vschema.yml | 2 +- .github/workflows/cluster_endtoend_vtorc.yml | 2 +- .github/workflows/cluster_endtoend_vttablet_prscomplex.yml | 2 +- .github/workflows/cluster_endtoend_xb_backup.yml | 2 +- .github/workflows/cluster_endtoend_xb_recovery.yml | 2 +- .github/workflows/codecov.yml | 2 +- .github/workflows/codeql_analysis.yml | 2 +- .github/workflows/create_release.yml | 2 +- .github/workflows/docker_test_cluster_10.yml | 2 +- .github/workflows/docker_test_cluster_25.yml | 2 +- .github/workflows/e2e_race.yml | 2 +- .github/workflows/endtoend.yml | 2 +- .github/workflows/local_example.yml | 2 +- .github/workflows/region_example.yml | 2 +- .github/workflows/static_checks_etc.yml | 2 +- .github/workflows/unit_race.yml | 2 +- .github/workflows/unit_race_evalengine.yml | 2 +- .github/workflows/unit_test_evalengine_mysql57.yml | 2 +- .github/workflows/unit_test_evalengine_mysql80.yml | 2 +- .github/workflows/unit_test_mysql57.yml | 2 +- .github/workflows/unit_test_mysql80.yml | 2 +- .github/workflows/update_golang_dependencies.yml | 2 +- .github/workflows/update_golang_version.yml | 2 +- .github/workflows/upgrade_downgrade_test_backups_e2e.yml | 2 +- .../upgrade_downgrade_test_backups_e2e_next_release.yml | 2 +- .github/workflows/upgrade_downgrade_test_backups_manual.yml | 2 +- .../upgrade_downgrade_test_backups_manual_next_release.yml | 2 +- .../upgrade_downgrade_test_query_serving_queries.yml | 2 +- ...de_downgrade_test_query_serving_queries_next_release.yml | 2 +- .../upgrade_downgrade_test_query_serving_schema.yml | 2 +- ...ade_downgrade_test_query_serving_schema_next_release.yml | 2 +- .../workflows/upgrade_downgrade_test_reparent_new_vtctl.yml | 2 +- .../upgrade_downgrade_test_reparent_new_vttablet.yml | 2 +- .../workflows/upgrade_downgrade_test_reparent_old_vtctl.yml | 2 +- .../upgrade_downgrade_test_reparent_old_vttablet.yml | 2 +- Makefile | 2 +- build.env | 2 +- docker/bootstrap/CHANGELOG.md | 6 +++++- docker/bootstrap/Dockerfile.common | 2 +- docker/lite/Dockerfile | 2 +- docker/lite/Dockerfile.percona80 | 2 +- docker/local/Dockerfile | 2 +- docker/vttestserver/Dockerfile.mysql80 | 2 +- go.mod | 2 +- test.go | 2 +- test/templates/cluster_endtoend_test.tpl | 2 +- test/templates/cluster_endtoend_test_docker.tpl | 2 +- test/templates/cluster_endtoend_test_mysql57.tpl | 2 +- test/templates/dockerfile.tpl | 2 +- test/templates/unit_test.tpl | 2 +- vitess-mixin/go.mod | 2 +- 107 files changed, 111 insertions(+), 107 deletions(-) diff --git a/.github/workflows/assign_milestone.yml b/.github/workflows/assign_milestone.yml index fd2258cbd93..52542ad4c90 100644 --- a/.github/workflows/assign_milestone.yml +++ b/.github/workflows/assign_milestone.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/check_make_vtadmin_authz_testgen.yml b/.github/workflows/check_make_vtadmin_authz_testgen.yml index dd6608f766a..182748ef5f7 100644 --- a/.github/workflows/check_make_vtadmin_authz_testgen.yml +++ b/.github/workflows/check_make_vtadmin_authz_testgen.yml @@ -50,7 +50,7 @@ jobs: uses: actions/setup-go@v5 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.vtadmin_changes == 'true' with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.vtadmin_changes == 'true' diff --git a/.github/workflows/check_make_vtadmin_web_proto.yml b/.github/workflows/check_make_vtadmin_web_proto.yml index df6ee528a0e..f8694ae93bb 100644 --- a/.github/workflows/check_make_vtadmin_web_proto.yml +++ b/.github/workflows/check_make_vtadmin_web_proto.yml @@ -52,7 +52,7 @@ jobs: uses: actions/setup-go@v5 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.proto_changes == 'true' with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Setup Node if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.proto_changes == 'true' diff --git a/.github/workflows/cluster_endtoend_12.yml b/.github/workflows/cluster_endtoend_12.yml index e9558f33a73..7c98dc21e03 100644 --- a/.github/workflows/cluster_endtoend_12.yml +++ b/.github/workflows/cluster_endtoend_12.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_13.yml b/.github/workflows/cluster_endtoend_13.yml index 012afa11807..86695e274cd 100644 --- a/.github/workflows/cluster_endtoend_13.yml +++ b/.github/workflows/cluster_endtoend_13.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_15.yml b/.github/workflows/cluster_endtoend_15.yml index c089026a128..d9090153390 100644 --- a/.github/workflows/cluster_endtoend_15.yml +++ b/.github/workflows/cluster_endtoend_15.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_18.yml b/.github/workflows/cluster_endtoend_18.yml index 1734eca79e1..9f02fe391e1 100644 --- a/.github/workflows/cluster_endtoend_18.yml +++ b/.github/workflows/cluster_endtoend_18.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_21.yml b/.github/workflows/cluster_endtoend_21.yml index 163d6a20d28..f2bfd7c86d4 100644 --- a/.github/workflows/cluster_endtoend_21.yml +++ b/.github/workflows/cluster_endtoend_21.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_22.yml b/.github/workflows/cluster_endtoend_22.yml index 19e008cb115..b94632fa223 100644 --- a/.github/workflows/cluster_endtoend_22.yml +++ b/.github/workflows/cluster_endtoend_22.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_backup_pitr.yml b/.github/workflows/cluster_endtoend_backup_pitr.yml index 2c06218d198..a8d81803f22 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml index 6887ede16ad..c514999d150 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml index 3c59c3c4b68..3059c3a3403 100644 --- a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml +++ b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_mysql80.yml b/.github/workflows/cluster_endtoend_mysql80.yml index 40e26b36445..c2740f08370 100644 --- a/.github/workflows/cluster_endtoend_mysql80.yml +++ b/.github/workflows/cluster_endtoend_mysql80.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_mysql_server_vault.yml b/.github/workflows/cluster_endtoend_mysql_server_vault.yml index dbb77b37b45..9414da50b31 100644 --- a/.github/workflows/cluster_endtoend_mysql_server_vault.yml +++ b/.github/workflows/cluster_endtoend_mysql_server_vault.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_revert.yml b/.github/workflows/cluster_endtoend_onlineddl_revert.yml index d4dfef915ad..8b55bb716dd 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_revert.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_revert.yml @@ -74,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml index 6d12d8bd5a0..153442fa236 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml @@ -74,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml index b7f0db9db46..e90465ff31e 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml @@ -74,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml index dc731b09f8b..13bfb04f43e 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml @@ -74,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml index 24bfbd1f8ea..c7d8de9f21a 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml @@ -74,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml index 8922e25cd2b..75e2d2bcbaf 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml @@ -74,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml index 19d55d0f613..2f2ecdceb01 100644 --- a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml +++ b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml @@ -74,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml index 2d0d42ac59e..3cbec4b81f2 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml index 795a67833e8..07eb70d1348 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml index 2ed58e21628..1446042c7cc 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_topo_connection_cache.yml b/.github/workflows/cluster_endtoend_topo_connection_cache.yml index 22ea9f84816..03542a9f014 100644 --- a/.github/workflows/cluster_endtoend_topo_connection_cache.yml +++ b/.github/workflows/cluster_endtoend_topo_connection_cache.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml index 8fb159404ab..a9fa2711c65 100644 --- a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml +++ b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_basic.yml b/.github/workflows/cluster_endtoend_vreplication_basic.yml index eff4dad0846..09a354b1701 100644 --- a/.github/workflows/cluster_endtoend_vreplication_basic.yml +++ b/.github/workflows/cluster_endtoend_vreplication_basic.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml index eacbc0ff34f..46f2ff602fb 100644 --- a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml +++ b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml b/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml index 9995379cf7c..bd4ea33ca7c 100644 --- a/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml +++ b/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml index 197a3377242..be47a10d6cf 100644 --- a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml +++ b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml b/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml index dd8201cd922..40196062a2e 100644 --- a/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml +++ b/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml b/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml index 0246e0fbf3c..278cdaa5d24 100644 --- a/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml +++ b/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml b/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml index 2523b982e4e..ef0dbe4f7d2 100644 --- a/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml +++ b/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml index 4125b1f9946..7b05b9acf1e 100644 --- a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml +++ b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vreplication_v2.yml b/.github/workflows/cluster_endtoend_vreplication_v2.yml index 6c280f83547..183aa917b8d 100644 --- a/.github/workflows/cluster_endtoend_vreplication_v2.yml +++ b/.github/workflows/cluster_endtoend_vreplication_v2.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vstream.yml b/.github/workflows/cluster_endtoend_vstream.yml index 79a9278def2..9065b6dcc21 100644 --- a/.github/workflows/cluster_endtoend_vstream.yml +++ b/.github/workflows/cluster_endtoend_vstream.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtbackup.yml b/.github/workflows/cluster_endtoend_vtbackup.yml index 7905778ce8c..0f7abc581e3 100644 --- a/.github/workflows/cluster_endtoend_vtbackup.yml +++ b/.github/workflows/cluster_endtoend_vtbackup.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml index 5760c8c7251..760a4b3edd7 100644 --- a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml index fd29ba2184b..ff51270d6c7 100644 --- a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml +++ b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml index f7e01ff1462..048f6209b9c 100644 --- a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml +++ b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_gen4.yml b/.github/workflows/cluster_endtoend_vtgate_gen4.yml index 18bd53252da..45792956826 100644 --- a/.github/workflows/cluster_endtoend_vtgate_gen4.yml +++ b/.github/workflows/cluster_endtoend_vtgate_gen4.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml index 8a4d037d197..9d2cb912597 100644 --- a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_godriver.yml b/.github/workflows/cluster_endtoend_vtgate_godriver.yml index 4e7b40f7bf9..1e52f4a6024 100644 --- a/.github/workflows/cluster_endtoend_vtgate_godriver.yml +++ b/.github/workflows/cluster_endtoend_vtgate_godriver.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml index 35691664026..e742efc1b16 100644 --- a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml +++ b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_queries.yml b/.github/workflows/cluster_endtoend_vtgate_queries.yml index 5c8b2032c0a..0410ef04354 100644 --- a/.github/workflows/cluster_endtoend_vtgate_queries.yml +++ b/.github/workflows/cluster_endtoend_vtgate_queries.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml index cac04f07f48..4d9b9c72fb2 100644 --- a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml +++ b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml index 52e0b191ab5..b8e3aa878b2 100644 --- a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml +++ b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_schema.yml b/.github/workflows/cluster_endtoend_vtgate_schema.yml index f0a61b6b1f3..463044caeae 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml index e728cea0ff3..3bf1f6b2547 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml index 9535cb586d2..a88c0bebb3b 100644 --- a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml +++ b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_topo.yml b/.github/workflows/cluster_endtoend_vtgate_topo.yml index 40a16d1bd9d..0101eba229a 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml index 631c4e15c4e..12fc3e5d5f3 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml index f4f8005d850..184353b2731 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_transaction.yml b/.github/workflows/cluster_endtoend_vtgate_transaction.yml index 58690ed4bc0..e85a919902d 100644 --- a/.github/workflows/cluster_endtoend_vtgate_transaction.yml +++ b/.github/workflows/cluster_endtoend_vtgate_transaction.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml index ae742e8ba6d..314d1dde312 100644 --- a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml +++ b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml index ea21e597d8f..9ed165fbd17 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtgate_vschema.yml b/.github/workflows/cluster_endtoend_vtgate_vschema.yml index 098277a15fa..3731b54376f 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vschema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vschema.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vtorc.yml b/.github/workflows/cluster_endtoend_vtorc.yml index 8b0aadbd8d6..fc65f0c126a 100644 --- a/.github/workflows/cluster_endtoend_vtorc.yml +++ b/.github/workflows/cluster_endtoend_vtorc.yml @@ -82,7 +82,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml index e2e6247d492..6ee747c28ab 100644 --- a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml +++ b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_xb_backup.yml b/.github/workflows/cluster_endtoend_xb_backup.yml index a6ca9447469..c407a83d9ca 100644 --- a/.github/workflows/cluster_endtoend_xb_backup.yml +++ b/.github/workflows/cluster_endtoend_xb_backup.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/cluster_endtoend_xb_recovery.yml b/.github/workflows/cluster_endtoend_xb_recovery.yml index 4a662d5f5e9..0e18e301f51 100644 --- a/.github/workflows/cluster_endtoend_xb_recovery.yml +++ b/.github/workflows/cluster_endtoend_xb_recovery.yml @@ -73,7 +73,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index b467bef83a1..c277733a04a 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -32,7 +32,7 @@ jobs: if: steps.changes.outputs.changed_files == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.changes.outputs.changed_files == 'true' diff --git a/.github/workflows/codeql_analysis.yml b/.github/workflows/codeql_analysis.yml index 3b109b81307..c822cbee089 100644 --- a/.github/workflows/codeql_analysis.yml +++ b/.github/workflows/codeql_analysis.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index a44a01ce71d..33a7df3208c 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Setup node uses: actions/setup-node@v4 diff --git a/.github/workflows/docker_test_cluster_10.yml b/.github/workflows/docker_test_cluster_10.yml index ec73bb8702a..ff3bbaf6e68 100644 --- a/.github/workflows/docker_test_cluster_10.yml +++ b/.github/workflows/docker_test_cluster_10.yml @@ -54,7 +54,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/docker_test_cluster_25.yml b/.github/workflows/docker_test_cluster_25.yml index 95f284c41ac..9e60e3a4b50 100644 --- a/.github/workflows/docker_test_cluster_25.yml +++ b/.github/workflows/docker_test_cluster_25.yml @@ -54,7 +54,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/e2e_race.yml b/.github/workflows/e2e_race.yml index 6e23f1fbffc..61e7349790d 100644 --- a/.github/workflows/e2e_race.yml +++ b/.github/workflows/e2e_race.yml @@ -52,7 +52,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/endtoend.yml b/.github/workflows/endtoend.yml index f7d974ff5b3..ef390dae4eb 100644 --- a/.github/workflows/endtoend.yml +++ b/.github/workflows/endtoend.yml @@ -52,7 +52,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index 717bad90223..20c8e0ab1d3 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -57,7 +57,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - uses: actions/setup-node@v4 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml index abaeb1aca48..f73e8769c9a 100644 --- a/.github/workflows/region_example.yml +++ b/.github/workflows/region_example.yml @@ -57,7 +57,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - uses: actions/setup-node@v4 if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.examples == 'true' diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml index cbca1475c46..65e29b67ba6 100644 --- a/.github/workflows/static_checks_etc.yml +++ b/.github/workflows/static_checks_etc.yml @@ -113,7 +113,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && (steps.changes.outputs.go_files == 'true' || steps.changes.outputs.parser_changes == 'true' || steps.changes.outputs.proto_changes == 'true') uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.go_files == 'true' diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml index 88b8bfe5a36..c07bad84490 100644 --- a/.github/workflows/unit_race.yml +++ b/.github/workflows/unit_race.yml @@ -69,7 +69,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/unit_race_evalengine.yml b/.github/workflows/unit_race_evalengine.yml index cdcdfd680be..0de2d60a5ae 100644 --- a/.github/workflows/unit_race_evalengine.yml +++ b/.github/workflows/unit_race_evalengine.yml @@ -69,7 +69,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/unit_test_evalengine_mysql57.yml b/.github/workflows/unit_test_evalengine_mysql57.yml index 49410e597ba..70583c4216a 100644 --- a/.github/workflows/unit_test_evalengine_mysql57.yml +++ b/.github/workflows/unit_test_evalengine_mysql57.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/unit_test_evalengine_mysql80.yml b/.github/workflows/unit_test_evalengine_mysql80.yml index e400c5bcf74..d5d90ebb912 100644 --- a/.github/workflows/unit_test_evalengine_mysql80.yml +++ b/.github/workflows/unit_test_evalengine_mysql80.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/unit_test_mysql57.yml b/.github/workflows/unit_test_mysql57.yml index 616bcf28e54..03ecf100e72 100644 --- a/.github/workflows/unit_test_mysql57.yml +++ b/.github/workflows/unit_test_mysql57.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/unit_test_mysql80.yml b/.github/workflows/unit_test_mysql80.yml index 970127fce37..d6a0b1bd08c 100644 --- a/.github/workflows/unit_test_mysql80.yml +++ b/.github/workflows/unit_test_mysql80.yml @@ -71,7 +71,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/update_golang_dependencies.yml b/.github/workflows/update_golang_dependencies.yml index 25dd835919f..0523eed6a97 100644 --- a/.github/workflows/update_golang_dependencies.yml +++ b/.github/workflows/update_golang_dependencies.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Check out code uses: actions/checkout@v4 diff --git a/.github/workflows/update_golang_version.yml b/.github/workflows/update_golang_version.yml index f44458c63d8..59daadb8f3a 100644 --- a/.github/workflows/update_golang_version.yml +++ b/.github/workflows/update_golang_version.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Check out code uses: actions/checkout@v4 diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml index d26eaa5bf59..209c96fd539 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml @@ -72,7 +72,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml index c09b3ac6636..542c6a00483 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml @@ -74,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml index 462471422db..e0d7402c8ce 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml @@ -76,7 +76,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml index 25e4abea54f..15aa0f05a19 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml @@ -77,7 +77,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml index 30be98ee25a..9926336f9c7 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml @@ -75,7 +75,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml index 91b2787a86a..233dd496a21 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml @@ -76,7 +76,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml index 6b38354c7ed..6664951d12c 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml @@ -75,7 +75,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml index 605440b2f55..d9a31b56ffe 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml @@ -76,7 +76,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml index f1dd0384002..a6e533cf735 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml @@ -76,7 +76,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml index e83c6948bba..e13520fc46a 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml @@ -76,7 +76,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml index 6c898d4bd16..dcfdf06ae65 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml @@ -75,7 +75,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml index fe6a426f97a..9fec80feced 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml @@ -75,7 +75,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/Makefile b/Makefile index b9387741274..91cafd489d5 100644 --- a/Makefile +++ b/Makefile @@ -282,7 +282,7 @@ $(PROTO_GO_OUTS): minimaltools install_protoc-gen-go proto/*.proto # This rule builds the bootstrap images for all flavors. DOCKER_IMAGES_FOR_TEST = mysql57 mysql80 percona57 percona80 DOCKER_IMAGES = common $(DOCKER_IMAGES_FOR_TEST) -BOOTSTRAP_VERSION=32 +BOOTSTRAP_VERSION=33 ensure_bootstrap_version: find docker/ -type f -exec sed -i "s/^\(ARG bootstrap_version\)=.*/\1=${BOOTSTRAP_VERSION}/" {} \; sed -i 's/\(^.*flag.String(\"bootstrap-version\",\) *\"[^\"]\+\"/\1 \"${BOOTSTRAP_VERSION}\"/' test.go diff --git a/build.env b/build.env index 34da6721aa7..18e3069fe09 100755 --- a/build.env +++ b/build.env @@ -17,7 +17,7 @@ source ./tools/shell_functions.inc go version >/dev/null 2>&1 || fail "Go is not installed or is not in \$PATH. See https://vitess.io/contributing/build-from-source for install instructions." -goversion_min 1.22.3 || echo "Go version reported: `go version`. Version 1.22.3+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." +goversion_min 1.22.4 || echo "Go version reported: `go version`. Version 1.22.4+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." mkdir -p dist mkdir -p bin diff --git a/docker/bootstrap/CHANGELOG.md b/docker/bootstrap/CHANGELOG.md index 8d80bbea69b..1fe7f8d6acb 100644 --- a/docker/bootstrap/CHANGELOG.md +++ b/docker/bootstrap/CHANGELOG.md @@ -124,4 +124,8 @@ List of changes between bootstrap image versions. ## [32] - 2024-05-07 ### Changes -- Update build to golang 1.22.3 \ No newline at end of file +- Update build to golang 1.22.3 + +## [33] - 2024-06-05 +### Changes +- Update build to golang 1.22.4 \ No newline at end of file diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 12dc2d98407..7e340b79cd7 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 golang:1.22.3-bullseye +FROM --platform=linux/amd64 golang:1.22.4-bullseye # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ diff --git a/docker/lite/Dockerfile b/docker/lite/Dockerfile index 90e29bf93ac..d5c46cac133 100644 --- a/docker/lite/Dockerfile +++ b/docker/lite/Dockerfile @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=32 +ARG bootstrap_version=33 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index f27e8a4e493..96523044eff 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=32 +ARG bootstrap_version=33 ARG image="vitess/bootstrap:${bootstrap_version}-percona80" FROM "${image}" AS builder diff --git a/docker/local/Dockerfile b/docker/local/Dockerfile index b7d5b509562..33c2dfd6cd8 100644 --- a/docker/local/Dockerfile +++ b/docker/local/Dockerfile @@ -1,4 +1,4 @@ -ARG bootstrap_version=32 +ARG bootstrap_version=33 ARG image="vitess/bootstrap:${bootstrap_version}-common" FROM "${image}" diff --git a/docker/vttestserver/Dockerfile.mysql80 b/docker/vttestserver/Dockerfile.mysql80 index 14fd0466dcb..7f1d989ee5b 100644 --- a/docker/vttestserver/Dockerfile.mysql80 +++ b/docker/vttestserver/Dockerfile.mysql80 @@ -17,7 +17,7 @@ # ensure images contain the right binaries. # Use a temporary layer for the build stage. -ARG bootstrap_version=32 +ARG bootstrap_version=33 ARG image="vitess/bootstrap:${bootstrap_version}-mysql80" FROM "${image}" AS builder diff --git a/go.mod b/go.mod index c9351265209..2f31495ee11 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module vitess.io/vitess -go 1.22.3 +go 1.22.4 require ( cloud.google.com/go/storage v1.41.0 diff --git a/test.go b/test.go index 101f2dc01bf..ef0a28bafe0 100755 --- a/test.go +++ b/test.go @@ -77,7 +77,7 @@ For example: // Flags var ( flavor = flag.String("flavor", "mysql80", "comma-separated bootstrap flavor(s) to run against (when using Docker mode). Available flavors: all,"+flavors) - bootstrapVersion = flag.String("bootstrap-version", "32", "the version identifier to use for the docker images") + bootstrapVersion = flag.String("bootstrap-version", "33", "the version identifier to use for the docker images") runCount = flag.Int("runs", 1, "run each test this many times") retryMax = flag.Int("retry", 3, "max number of retries, to detect flaky tests") logPass = flag.Bool("log-pass", false, "log test output even if it passes") diff --git a/test/templates/cluster_endtoend_test.tpl b/test/templates/cluster_endtoend_test.tpl index 8dadd7b73be..c6837170c20 100644 --- a/test/templates/cluster_endtoend_test.tpl +++ b/test/templates/cluster_endtoend_test.tpl @@ -87,7 +87,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/test/templates/cluster_endtoend_test_docker.tpl b/test/templates/cluster_endtoend_test_docker.tpl index 650fc81a57a..9aa49df5f18 100644 --- a/test/templates/cluster_endtoend_test_docker.tpl +++ b/test/templates/cluster_endtoend_test_docker.tpl @@ -56,7 +56,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Tune the OS if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/test/templates/cluster_endtoend_test_mysql57.tpl b/test/templates/cluster_endtoend_test_mysql57.tpl index fba14ffc0d8..c22d394c8c5 100644 --- a/test/templates/cluster_endtoend_test_mysql57.tpl +++ b/test/templates/cluster_endtoend_test_mysql57.tpl @@ -92,7 +92,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/test/templates/dockerfile.tpl b/test/templates/dockerfile.tpl index 38cd2b93d9f..502e553cabf 100644 --- a/test/templates/dockerfile.tpl +++ b/test/templates/dockerfile.tpl @@ -1,4 +1,4 @@ -ARG bootstrap_version=32 +ARG bootstrap_version=33 ARG image="vitess/bootstrap:${bootstrap_version}-{{.Platform}}" FROM "${image}" diff --git a/test/templates/unit_test.tpl b/test/templates/unit_test.tpl index 94350008767..17782da2fa1 100644 --- a/test/templates/unit_test.tpl +++ b/test/templates/unit_test.tpl @@ -69,7 +69,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' diff --git a/vitess-mixin/go.mod b/vitess-mixin/go.mod index 6251472c550..591803ff433 100644 --- a/vitess-mixin/go.mod +++ b/vitess-mixin/go.mod @@ -1,6 +1,6 @@ module vitess-mixin -go 1.22.3 +go 1.22.4 require ( github.com/evanphx/json-patch v5.9.0+incompatible From 2df3545a10ef36b0acd95e93561c2ca8feea98f2 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 5 Jun 2024 06:58:21 +0300 Subject: [PATCH 04/40] CI upgrade/downgrade tests for Online DDL / throttler / vreplication flow (#16017) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Co-authored-by: Florent Poinsard <35779988+frouioui@users.noreply.github.com> --- .../upgrade_downgrade_test_onlineddl_flow.yml | 258 +++++++ go/test/endtoend/cluster/cluster_process.go | 12 + .../onlineddl/flow/onlineddl_flow_test.go | 661 ++++++++++++++++++ test/config.json | 9 + 4 files changed, 940 insertions(+) create mode 100644 .github/workflows/upgrade_downgrade_test_onlineddl_flow.yml create mode 100644 go/test/endtoend/onlineddl/flow/onlineddl_flow_test.go diff --git a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml new file mode 100644 index 00000000000..d05283e482b --- /dev/null +++ b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml @@ -0,0 +1,258 @@ +name: Online DDL flow - Upgrade Downgrade Testing +on: + push: + pull_request: + +concurrency: + group: format('{0}-{1}', ${{ github.ref }}, 'Upgrade Downgrade Testing Online DDL flow') + cancel-in-progress: true + +permissions: read-all + +# This test ensures that our Online DDL + VReplication + throttler components +# work using primary and replica vttablets built on different versions. + +jobs: + + upgrade_downgrade_test: + name: Run Upgrade Downgrade Test - Online DDL flow + runs-on: gh-hosted-runners-16cores-1 + + steps: + - name: Skip CI + run: | + if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then + echo "skipping CI due to the 'Skip CI' label" + exit 1 + fi + + - name: Check if workflow needs to be skipped + id: skip-workflow + run: | + skip='false' + if [[ "${{github.event.pull_request}}" == "" ]] && [[ "${{github.ref}}" != "refs/heads/main" ]] && [[ ! "${{github.ref}}" =~ ^refs/heads/release-[0-9]+\.[0-9]$ ]] && [[ ! "${{github.ref}}" =~ "refs/tags/.*" ]]; then + skip='true' + fi + echo Skip ${skip} + echo "skip-workflow=${skip}" >> $GITHUB_OUTPUT + + - name: Check out commit's code + if: steps.skip-workflow.outputs.skip-workflow == 'false' + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check for changes in relevant files + if: steps.skip-workflow.outputs.skip-workflow == 'false' + uses: dorny/paths-filter@v3.0.1 + id: changes + with: + token: '' + filters: | + end_to_end: + - 'go/**' + - 'go/**/*.go' + - 'test.go' + - 'Makefile' + - 'build.env' + - 'go.sum' + - 'go.mod' + - 'proto/*.proto' + - 'tools/**' + - 'config/**' + - 'bootstrap.sh' + - '.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml' + + - name: Set output with latest release branch + id: output-previous-release-ref + if: steps.skip-workflow.outputs.skip-workflow == 'false' + run: | + previous_release_ref=$(./tools/get_previous_release.sh ${{github.base_ref}} ${{github.ref}}) + echo $previous_release_ref + echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT + + - name: Set output with next release branch + if: steps.skip-workflow.outputs.skip-workflow == 'false' + id: output-next-release-ref + run: | + next_release_ref=$(./tools/get_next_release.sh ${{github.base_ref}} ${{github.ref}}) + echo $next_release_ref + echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT + + - name: Set up Go + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@v5 + with: + go-version: 1.22.3 + + - name: Set up python + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-python@v5 + + - name: Tune the OS + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" + + - name: Get base dependencies + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + sudo DEBIAN_FRONTEND="noninteractive" apt-get update + # Uninstall any previously installed MySQL first + sudo systemctl stop apparmor + sudo DEBIAN_FRONTEND="noninteractive" apt-get remove -y --purge mysql-server mysql-client mysql-common + sudo apt-get -y autoremove + sudo apt-get -y autoclean + sudo deluser mysql + sudo rm -rf /var/lib/mysql + sudo rm -rf /etc/mysql + # Install mysql80 + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys A8D3785C + wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb + echo mysql-apt-config mysql-apt-config/select-server select mysql-8.0 | sudo debconf-set-selections + sudo DEBIAN_FRONTEND="noninteractive" dpkg -i mysql-apt-config* + sudo apt-get update + sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y mysql-server mysql-client + # Install everything else we need, and configure + sudo apt-get install -y make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo bash -c "echo '/usr/sbin/mysqld { }' > /etc/apparmor.d/usr.sbin.mysqld" # https://bugs.launchpad.net/ubuntu/+source/mariadb-10.1/+bug/1806263 + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld || echo "could not remove mysqld profile" + + # install JUnit report formatter + go install github.com/vitessio/go-junit-report@HEAD + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install -y percona-xtrabackup-24 + + # Checkout to the last release of Vitess + - name: Check out last version's code (${{ steps.output-previous-release-ref.outputs.previous_release_ref }}) + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/checkout@v4 + with: + ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} + + - name: Get dependencies for the last release + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + go mod download + + - name: Building last release's binaries + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 + run: | + source build.env + make build + mkdir -p /tmp/vitess-build-last/ + cp -R bin /tmp/vitess-build-last/ + rm -Rf bin/* + + # Checkout to the next release of Vitess + - name: Check out next version's code (${{ steps.output-next-release-ref.outputs.next_release_ref }}) + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/checkout@v4 + with: + ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} + + - name: Get dependencies for the next release + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + go mod download + + - name: Building next release's binaries + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 + run: | + source build.env + NOVTADMINBUILD=1 make build + mkdir -p /tmp/vitess-build-next/ + cp -R bin /tmp/vitess-build-next/ + rm -Rf bin/* + + # Checkout to this build's commit + - name: Check out commit's code + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + uses: actions/checkout@v4 + + - name: Get dependencies for this commit + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + go mod download + + - name: Building the binaries for this commit + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 + run: | + source build.env + make build + mkdir -p /tmp/vitess-build-current/ + cp -R bin /tmp/vitess-build-current/ + + # Copy vttablet and related binaries under new names + - name: Use current version Vtctl, and other version VTTablet + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + source build.env + + cp /tmp/vitess-build-last/bin/vttablet $PWD/bin/vttablet-last + cp /tmp/vitess-build-last/bin/mysqlctl $PWD/bin/mysqlctl-last + cp /tmp/vitess-build-last/bin/mysqlctld $PWD/bin/mysqlctld-last + cp /tmp/vitess-build-next/bin/vttablet $PWD/bin/vttablet-next + cp /tmp/vitess-build-next/bin/mysqlctl $PWD/bin/mysqlctl-next + cp /tmp/vitess-build-next/bin/mysqlctld $PWD/bin/mysqlctld-next + $PWD/bin/vttablet-last --version + $PWD/bin/vttablet --version + $PWD/bin/vttablet-next --version + + # Running a test with primary tablet at version n (current SHA) and replica vttablet at version n-1 + - name: Run Online DDL tests (primary=N, replica=N-1) + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + rm -rf /tmp/vtdataroot + mkdir -p /tmp/vtdataroot + + source build.env + export PRIMARY_TABLET_BINARY_SUFFIX="" + export REPLICA_TABLET_BINARY_SUFFIX="-last" + eatmydata -- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_onlineddl_flow + + # Running a test with primary tablet at version n-1 and replica vttablet at version n (current SHA) + - name: Run Online DDL tests (primary=N-1, replica=N) + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + rm -rf /tmp/vtdataroot + mkdir -p /tmp/vtdataroot + + source build.env + export PRIMARY_TABLET_BINARY_SUFFIX="-last" + export REPLICA_TABLET_BINARY_SUFFIX="" + eatmydata -- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_onlineddl_flow + + # Running a test with primary tablet at version n+1 and replica vttablet at version n (current SHA) + - name: Run Online DDL tests (primary=N+1, replica=N) + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + rm -rf /tmp/vtdataroot + mkdir -p /tmp/vtdataroot + + source build.env + export PRIMARY_TABLET_BINARY_SUFFIX="-next" + export REPLICA_TABLET_BINARY_SUFFIX="" + eatmydata -- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_onlineddl_flow + + # Running a test with primary tablet at version n (current SHA) and replica vttablet at version n+1 + - name: Run Online DDL tests (primary=N, replica=N+1) + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' + run: | + rm -rf /tmp/vtdataroot + mkdir -p /tmp/vtdataroot + + source build.env + export PRIMARY_TABLET_BINARY_SUFFIX="" + export REPLICA_TABLET_BINARY_SUFFIX="-next" + eatmydata -- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_onlineddl_flow diff --git a/go/test/endtoend/cluster/cluster_process.go b/go/test/endtoend/cluster/cluster_process.go index 0fc5edef1bb..44636b3cdb6 100644 --- a/go/test/endtoend/cluster/cluster_process.go +++ b/go/test/endtoend/cluster/cluster_process.go @@ -403,6 +403,12 @@ func (cluster *LocalProcessCluster) startKeyspace(keyspace Keyspace, shardNames if err != nil { return err } + switch tablet.Type { + case "primary": + mysqlctlProcess.Binary += os.Getenv("PRIMARY_TABLET_BINARY_SUFFIX") + case "replica": + mysqlctlProcess.Binary += os.Getenv("REPLICA_TABLET_BINARY_SUFFIX") + } tablet.MysqlctlProcess = *mysqlctlProcess proc, err := tablet.MysqlctlProcess.StartProcess() if err != nil { @@ -426,6 +432,12 @@ func (cluster *LocalProcessCluster) startKeyspace(keyspace Keyspace, shardNames cluster.TmpDirectory, cluster.VtTabletExtraArgs, cluster.DefaultCharset) + switch tablet.Type { + case "primary": + tablet.VttabletProcess.Binary += os.Getenv("PRIMARY_TABLET_BINARY_SUFFIX") + case "replica": + tablet.VttabletProcess.Binary += os.Getenv("REPLICA_TABLET_BINARY_SUFFIX") + } tablet.Alias = tablet.VttabletProcess.TabletPath if cluster.ReusingVTDATAROOT { tablet.VttabletProcess.ServingStatus = "SERVING" diff --git a/go/test/endtoend/onlineddl/flow/onlineddl_flow_test.go b/go/test/endtoend/onlineddl/flow/onlineddl_flow_test.go new file mode 100644 index 00000000000..772a5fa6fd0 --- /dev/null +++ b/go/test/endtoend/onlineddl/flow/onlineddl_flow_test.go @@ -0,0 +1,661 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// This test is designed to test the flow of a single online DDL migration, with tablet throttler +// enabled. IT tests the following: +// - A primary + replica setup +// - Creating and populating a table +// - Enabling tablet (lag) throttler +// - Running a workload that generates DMLs, and which checks the throttler +// - Running an online DDL migration: +// - Using `online --postpone-completion` to use vreplication +// - vreplication configured (by default) to read from replica +// - vreplication by nature also checks the throttler +// - meanwhile, the workload generates DMLs, give migration some run time +// - proactively throttle and then unthrottle the migration +// - complete the migration +// +// - Validate sufficient DML has been applied +// - Validate the migration completed, and validate new schema is instated +// +// The test is designed with upgrade/downgrade in mind. In particular, we wish to test +// different vitess versions for `primary` and `replica` tablets. Thus, we validate: +// - Cross tablet and cross version throttler communication +// - Cross version vreplication + +package flow + +import ( + "context" + "flag" + "fmt" + "io" + "math/rand/v2" + "net/http" + "os" + "path" + "runtime" + "strings" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/test/endtoend/cluster" + "vitess.io/vitess/go/test/endtoend/onlineddl" + "vitess.io/vitess/go/test/endtoend/throttler" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/schema" + "vitess.io/vitess/go/vt/vttablet" + throttlebase "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/base" + "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp" +) + +var ( + clusterInstance *cluster.LocalProcessCluster + shards []cluster.Shard + vtParams mysql.ConnParams + primaryTablet *cluster.Vttablet + replicaTablet *cluster.Vttablet + tablets []*cluster.Vttablet + httpClient = throttlebase.SetupHTTPClient(time.Second) + throttleWorkload atomic.Bool + totalAppliedDML atomic.Int64 + + hostname = "localhost" + keyspaceName = "ks" + cell = "zone1" + schemaChangeDirectory = "" + tableName = `stress_test` + createStatement = ` + CREATE TABLE stress_test ( + id bigint(20) not null, + rand_val varchar(32) null default '', + hint_col varchar(64) not null default '', + created_timestamp timestamp not null default current_timestamp, + updates int unsigned not null default 0, + PRIMARY KEY (id), + key created_idx(created_timestamp), + key updates_idx(updates) + ) ENGINE=InnoDB + ` + alterHintStatement = ` + ALTER TABLE stress_test modify hint_col varchar(64) not null default '%s' + ` + insertRowStatement = ` + INSERT IGNORE INTO stress_test (id, rand_val) VALUES (%d, left(md5(rand()), 8)) + ` + updateRowStatement = ` + UPDATE stress_test SET updates=updates+1 WHERE id=%d + ` + deleteRowStatement = ` + DELETE FROM stress_test WHERE id=%d AND updates=1 + ` +) + +var ( + countIterations = 5 +) + +const ( + maxTableRows = 4096 + workloadDuration = 5 * time.Second + migrationWaitTimeout = 60 * time.Second +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + exitcode, err := func() (int, error) { + clusterInstance = cluster.NewCluster(cell, hostname) + schemaChangeDirectory = path.Join("/tmp", fmt.Sprintf("schema_change_dir_%d", clusterInstance.GetAndReserveTabletUID())) + defer os.RemoveAll(schemaChangeDirectory) + defer clusterInstance.Teardown() + + if _, err := os.Stat(schemaChangeDirectory); os.IsNotExist(err) { + _ = os.Mkdir(schemaChangeDirectory, 0700) + } + + clusterInstance.VtctldExtraArgs = []string{ + "--schema_change_dir", schemaChangeDirectory, + "--schema_change_controller", "local", + "--schema_change_check_interval", "1s", + } + + clusterInstance.VtTabletExtraArgs = []string{ + "--heartbeat_interval", "250ms", + "--heartbeat_on_demand_duration", "5s", + "--migration_check_interval", "2s", + "--watch_replication_stream", + // Test VPlayer batching mode. + fmt.Sprintf("--vreplication_experimental_flags=%d", + vttablet.VReplicationExperimentalFlagAllowNoBlobBinlogRowImage|vttablet.VReplicationExperimentalFlagOptimizeInserts|vttablet.VReplicationExperimentalFlagVPlayerBatching), + } + clusterInstance.VtGateExtraArgs = []string{ + "--ddl_strategy", "online", + } + + if err := clusterInstance.StartTopo(); err != nil { + return 1, err + } + + // Start keyspace + keyspace := &cluster.Keyspace{ + Name: keyspaceName, + } + + // No need for replicas in this stress test + if err := clusterInstance.StartKeyspace(*keyspace, []string{"1"}, 1, false); err != nil { + return 1, err + } + + // Collect table paths and ports + tablets = clusterInstance.Keyspaces[0].Shards[0].Vttablets + for _, tablet := range tablets { + if tablet.Type == "primary" { + primaryTablet = tablet + } else { + replicaTablet = tablet + } + } + + vtgateInstance := clusterInstance.NewVtgateInstance() + // Start vtgate + if err := vtgateInstance.Setup(); err != nil { + return 1, err + } + // ensure it is torn down during cluster TearDown + clusterInstance.VtgateProcess = *vtgateInstance + vtParams = mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + } + + return m.Run(), nil + }() + if err != nil { + fmt.Printf("%v\n", err) + os.Exit(1) + } else { + os.Exit(exitcode) + } + +} + +func TestSchemaChange(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + + require.NotNil(t, clusterInstance) + require.NotNil(t, primaryTablet) + require.NotNil(t, replicaTablet) + require.Equal(t, 2, len(tablets)) + + // This test is designed with upgrade/downgrade in mind. Do some logging to show what's + // the configuration for this test. + if binarySuffix := os.Getenv("PRIMARY_TABLET_BINARY_SUFFIX"); binarySuffix != "" { + t.Logf("Using PRIMARY_TABLET_BINARY_SUFFIX: %s", binarySuffix) + } + if binarySuffix := os.Getenv("REPLICA_TABLET_BINARY_SUFFIX"); binarySuffix != "" { + t.Logf("Using REPLICA_TABLET_BINARY_SUFFIX: %s", binarySuffix) + } + + require.NotEmpty(t, clusterInstance.Keyspaces) + shards = clusterInstance.Keyspaces[0].Shards + require.Equal(t, 1, len(shards)) + + throttler.EnableLagThrottlerAndWaitForStatus(t, clusterInstance, time.Second) + + t.Run("flow", func(t *testing.T) { + t.Run("create schema", func(t *testing.T) { + testWithInitialSchema(t) + }) + t.Run("init table", func(t *testing.T) { + // Populates table. Makes work for vcopier. + initTable(t) + }) + t.Run("migrate", func(t *testing.T) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + workloadCtx, cancelWorkload := context.WithCancel(ctx) + defer cancelWorkload() + + t.Run("routine throttler check", func(t *testing.T) { + go func() { + ticker := time.NewTicker(500 * time.Millisecond) + defer ticker.Stop() + for { + _, statusCode, err := throttlerCheck(primaryTablet.VttabletProcess, throttlerapp.OnlineDDLName) + assert.NoError(t, err) + throttleWorkload.Store(statusCode != http.StatusOK) + select { + case <-ticker.C: + case <-workloadCtx.Done(): + t.Logf("Terminating routine throttler check") + return + } + } + }() + }) + + var wg sync.WaitGroup + t.Run("generate workload", func(t *testing.T) { + // Create work for vplayer. + // This workload will consider throttling state and avoid generating DMLs if throttled. + wg.Add(1) + go func() { + defer cancel() + defer t.Logf("Terminating workload") + defer wg.Done() + runMultipleConnections(workloadCtx, t) + }() + }) + appliedDMLStart := totalAppliedDML.Load() + + hint := "post_completion_hint" + var uuid string + t.Run("submit migration", func(t *testing.T) { + uuid = testOnlineDDLStatement(t, fmt.Sprintf(alterHintStatement, hint), "online --postpone-completion", "", true) + }) + t.Run("wait for ready_to_complete", func(t *testing.T) { + waitForReadyToComplete(t, uuid, true) + }) + t.Run("validating running status", func(t *testing.T) { + onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusRunning) + }) + t.Run("throttle online-ddl", func(t *testing.T) { + onlineddl.ThrottleAllMigrations(t, &vtParams) + onlineddl.CheckThrottledApps(t, &vtParams, throttlerapp.OnlineDDLName, true) + + for _, tab := range tablets { + body, err := throttleApp(tab.VttabletProcess, throttlerapp.OnlineDDLName) + assert.NoError(t, err) + assert.Contains(t, body, throttlerapp.OnlineDDLName) + } + waitForThrottleCheckStatus(t, throttlerapp.OnlineDDLName, primaryTablet, http.StatusExpectationFailed) + }) + t.Run("unthrottle online-ddl", func(t *testing.T) { + onlineddl.UnthrottleAllMigrations(t, &vtParams) + onlineddl.CheckThrottledApps(t, &vtParams, throttlerapp.OnlineDDLName, false) + + for _, tab := range tablets { + body, err := unthrottleApp(tab.VttabletProcess, throttlerapp.OnlineDDLName) + assert.NoError(t, err) + assert.Contains(t, body, throttlerapp.OnlineDDLName) + } + waitForThrottleCheckStatus(t, throttlerapp.OnlineDDLName, primaryTablet, http.StatusOK) + }) + t.Run("additional wait", func(t *testing.T) { + // Waiting just so that we generate more DMLs, and give migration/vreplication + // more "opportunities" to throttle or to make progress. + select { + case <-time.After(3 * time.Second): + case <-ctx.Done(): + require.Fail(t, "context cancelled") + } + }) + t.Run("validate applied DML", func(t *testing.T) { + // Validate that during Online DDL, and even with throttling, we were + // able to produce meaningful traffic. + appliedDMLEnd := totalAppliedDML.Load() + assert.Greater(t, appliedDMLEnd, appliedDMLStart) + assert.GreaterOrEqual(t, appliedDMLEnd-appliedDMLStart, int64(maxTableRows)) + t.Logf("Applied DML: %d", appliedDMLEnd-appliedDMLStart) + }) + t.Run("attempt to complete", func(t *testing.T) { + onlineddl.CheckCompleteMigration(t, &vtParams, shards, uuid, true) + }) + isComplete := false + t.Run("optimistic wait for migration completion", func(t *testing.T) { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, uuid, migrationWaitTimeout, schema.OnlineDDLStatusRunning, schema.OnlineDDLStatusComplete) + isComplete = (status == schema.OnlineDDLStatusComplete) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + }) + if !isComplete { + t.Run("force complete cut-over", func(t *testing.T) { + onlineddl.CheckForceMigrationCutOver(t, &vtParams, shards, uuid, true) + }) + t.Run("another optimistic wait for migration completion", func(t *testing.T) { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, uuid, migrationWaitTimeout, schema.OnlineDDLStatusRunning, schema.OnlineDDLStatusComplete) + isComplete = (status == schema.OnlineDDLStatusComplete) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + }) + } + if !isComplete { + t.Run("terminate workload", func(t *testing.T) { + // Seems like workload is too high and preventing migration from completing. + // We can't go on forever. It's nice to have normal completion under workload, + // but it's not strictly what this test is designed for. We terminate the + // workload so as to allow the migration to complete. + cancelWorkload() + }) + } + t.Run("wait for migration completion", func(t *testing.T) { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, uuid, migrationWaitTimeout, schema.OnlineDDLStatusComplete) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusComplete) + }) + t.Run("validate table schema", func(t *testing.T) { + checkMigratedTable(t, tableName, hint) + }) + + cancelWorkload() // Early break + cancel() // Early break + wg.Wait() + }) + }) +} + +func testWithInitialSchema(t *testing.T) { + // Create the stress table + err := clusterInstance.VtctldClientProcess.ApplySchema(keyspaceName, createStatement) + require.Nil(t, err) + + // Check if table is created + checkTable(t, tableName) +} + +// testOnlineDDLStatement runs an online DDL, ALTER statement +func testOnlineDDLStatement(t *testing.T, alterStatement string, ddlStrategy string, expectHint string, skipWait bool) (uuid string) { + row := onlineddl.VtgateExecDDL(t, &vtParams, ddlStrategy, alterStatement, "").Named().Row() + require.NotNil(t, row) + uuid = row.AsString("uuid", "") + uuid = strings.TrimSpace(uuid) + require.NotEmpty(t, uuid) + fmt.Println("# Generated UUID (for debug purposes):") + fmt.Printf("<%s>\n", uuid) + + strategySetting, err := schema.ParseDDLStrategy(ddlStrategy) + assert.NoError(t, err) + + if !strategySetting.Strategy.IsDirect() && !skipWait && uuid != "" { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, uuid, migrationWaitTimeout, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + } + + if expectHint != "" { + checkMigratedTable(t, tableName, expectHint) + } + return uuid +} + +// checkTable checks the number of tables in the first two shards. +func checkTable(t *testing.T, showTableName string) { + for i := range clusterInstance.Keyspaces[0].Shards { + checkTablesCount(t, clusterInstance.Keyspaces[0].Shards[i].Vttablets[0], showTableName, 1) + } +} + +// checkTablesCount checks the number of tables in the given tablet +func checkTablesCount(t *testing.T, tablet *cluster.Vttablet, showTableName string, expectCount int) { + query := fmt.Sprintf(`show tables like '%%%s%%';`, showTableName) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + rowcount := 0 + + for { + queryResult, err := tablet.VttabletProcess.QueryTablet(query, keyspaceName, true) + require.Nil(t, err) + rowcount = len(queryResult.Rows) + if rowcount > 0 { + break + } + + select { + case <-ticker.C: + continue // Keep looping + case <-ctx.Done(): + // Break below to the assertion + } + + break + } + + assert.Equal(t, expectCount, rowcount) +} + +// checkMigratedTables checks the CREATE STATEMENT of a table after migration +func checkMigratedTable(t *testing.T, tableName, expectHint string) { + for i := range clusterInstance.Keyspaces[0].Shards { + createStatement := getCreateTableStatement(t, clusterInstance.Keyspaces[0].Shards[i].Vttablets[0], tableName) + assert.Contains(t, createStatement, expectHint) + } +} + +// getCreateTableStatement returns the CREATE TABLE statement for a given table +func getCreateTableStatement(t *testing.T, tablet *cluster.Vttablet, tableName string) (statement string) { + queryResult, err := tablet.VttabletProcess.QueryTablet(fmt.Sprintf("show create table %s;", tableName), keyspaceName, true) + require.Nil(t, err) + + assert.Equal(t, len(queryResult.Rows), 1) + assert.Equal(t, len(queryResult.Rows[0]), 2) // table name, create statement + statement = queryResult.Rows[0][1].ToString() + return statement +} + +func waitForReadyToComplete(t *testing.T, uuid string, expected bool) bool { + ctx, cancel := context.WithTimeout(context.Background(), migrationWaitTimeout) + defer cancel() + + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + for { + rs := onlineddl.ReadMigrations(t, &vtParams, uuid) + require.NotNil(t, rs) + for _, row := range rs.Named().Rows { + readyToComplete := row.AsInt64("ready_to_complete", 0) + if expected == (readyToComplete > 0) { + // all good. This is what we waited for + if expected { + // if migration is ready to complete, the timestamp should be non-null + assert.False(t, row["ready_to_complete_timestamp"].IsNull()) + } else { + assert.True(t, row["ready_to_complete_timestamp"].IsNull()) + } + return true + } + } + select { + case <-ticker.C: + case <-ctx.Done(): + assert.NoError(t, ctx.Err(), "timeout waiting for ready_to_complete") + return false + } + } +} + +func generateInsert(t *testing.T, conn *mysql.Conn) error { + id := rand.Int32N(int32(maxTableRows)) + query := fmt.Sprintf(insertRowStatement, id) + _, err := conn.ExecuteFetch(query, 1, false) + if err == nil { + totalAppliedDML.Add(1) + } + + return err +} + +func generateUpdate(t *testing.T, conn *mysql.Conn) error { + id := rand.Int32N(int32(maxTableRows)) + query := fmt.Sprintf(updateRowStatement, id) + _, err := conn.ExecuteFetch(query, 1, false) + if err == nil { + totalAppliedDML.Add(1) + } + + return err +} + +func generateDelete(t *testing.T, conn *mysql.Conn) error { + id := rand.Int32N(int32(maxTableRows)) + query := fmt.Sprintf(deleteRowStatement, id) + _, err := conn.ExecuteFetch(query, 1, false) + if err == nil { + totalAppliedDML.Add(1) + } + + return err +} + +func runSingleConnection(ctx context.Context, t *testing.T, sleepInterval time.Duration) { + log.Infof("Running single connection") + conn, err := mysql.Connect(ctx, &vtParams) + require.Nil(t, err) + defer conn.Close() + + _, err = conn.ExecuteFetch("set autocommit=1", 1000, true) + require.Nil(t, err) + _, err = conn.ExecuteFetch("set transaction isolation level read committed", 1000, true) + require.Nil(t, err) + + ticker := time.NewTicker(sleepInterval) + defer ticker.Stop() + + for { + if !throttleWorkload.Load() { + switch rand.Int32N(3) { + case 0: + err = generateInsert(t, conn) + case 1: + err = generateUpdate(t, conn) + case 2: + err = generateDelete(t, conn) + } + } + select { + case <-ctx.Done(): + log.Infof("Terminating single connection") + return + case <-ticker.C: + } + assert.Nil(t, err) + } +} + +func runMultipleConnections(ctx context.Context, t *testing.T) { + // The workload for a 16 vCPU machine is: + // - Concurrency of 16 + // - 2ms interval between queries for each connection + // As the number of vCPUs decreases, so do we decrease concurrency, and increase intervals. For example, on a 8 vCPU machine + // we run concurrency of 8 and interval of 4ms. On a 4 vCPU machine we run concurrency of 4 and interval of 8ms. + maxConcurrency := runtime.NumCPU() + sleepModifier := 16.0 / float64(maxConcurrency) + baseSleepInterval := 2 * time.Millisecond + singleConnectionSleepIntervalNanoseconds := float64(baseSleepInterval.Nanoseconds()) * sleepModifier + sleepInterval := time.Duration(int64(singleConnectionSleepIntervalNanoseconds)) + + log.Infof("Running multiple connections: maxConcurrency=%v, sleep interval=%v", maxConcurrency, sleepInterval) + var wg sync.WaitGroup + for i := 0; i < maxConcurrency; i++ { + wg.Add(1) + go func() { + defer wg.Done() + runSingleConnection(ctx, t, sleepInterval) + }() + } + wg.Wait() + log.Infof("Running multiple connections: done") +} + +func initTable(t *testing.T) { + log.Infof("initTable begin") + defer log.Infof("initTable complete") + + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.Nil(t, err) + defer conn.Close() + + appliedDMLStart := totalAppliedDML.Load() + + for i := 0; i < maxTableRows/2; i++ { + generateInsert(t, conn) + } + for i := 0; i < maxTableRows/4; i++ { + generateUpdate(t, conn) + } + for i := 0; i < maxTableRows/4; i++ { + generateDelete(t, conn) + } + appliedDMLEnd := totalAppliedDML.Load() + assert.Greater(t, appliedDMLEnd, appliedDMLStart) + assert.GreaterOrEqual(t, appliedDMLEnd-appliedDMLStart, int64(maxTableRows)) +} + +func throttleResponse(tablet *cluster.VttabletProcess, path string) (respBody string, err error) { + apiURL := fmt.Sprintf("http://%s:%d/%s", tablet.TabletHostname, tablet.Port, path) + resp, err := httpClient.Get(apiURL) + if err != nil { + return "", err + } + defer resp.Body.Close() + b, err := io.ReadAll(resp.Body) + respBody = string(b) + return respBody, err +} + +func throttleApp(tablet *cluster.VttabletProcess, throttlerApp throttlerapp.Name) (string, error) { + return throttleResponse(tablet, fmt.Sprintf("throttler/throttle-app?app=%s&duration=1h", throttlerApp.String())) +} + +func unthrottleApp(tablet *cluster.VttabletProcess, throttlerApp throttlerapp.Name) (string, error) { + return throttleResponse(tablet, fmt.Sprintf("throttler/unthrottle-app?app=%s", throttlerApp.String())) +} + +func throttlerCheck(tablet *cluster.VttabletProcess, throttlerApp throttlerapp.Name) (respBody string, statusCode int, err error) { + apiURL := fmt.Sprintf("http://%s:%d/throttler/check?app=%s", tablet.TabletHostname, tablet.Port, throttlerApp.String()) + resp, err := httpClient.Get(apiURL) + if err != nil { + return "", 0, err + } + defer resp.Body.Close() + statusCode = resp.StatusCode + b, err := io.ReadAll(resp.Body) + respBody = string(b) + return respBody, statusCode, err +} + +// waitForThrottleCheckStatus waits for the tablet to return the provided HTTP code in a throttle check +func waitForThrottleCheckStatus(t *testing.T, throttlerApp throttlerapp.Name, tablet *cluster.Vttablet, wantCode int) { + ctx, cancel := context.WithTimeout(context.Background(), migrationWaitTimeout) + defer cancel() + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + for { + respBody, statusCode, err := throttlerCheck(tablet.VttabletProcess, throttlerApp) + require.NoError(t, err) + + if wantCode == statusCode { + return + } + select { + case <-ctx.Done(): + assert.Equalf(t, wantCode, statusCode, "body: %s", respBody) + return + case <-ticker.C: + } + } +} diff --git a/test/config.json b/test/config.json index 2e612e57ca5..21c16af6caf 100644 --- a/test/config.json +++ b/test/config.json @@ -313,6 +313,15 @@ "RetryMax": 1, "Tags": [] }, + "onlineddl_flow": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/onlineddl/flow", "-timeout", "30m"], + "Command": [], + "Manual": false, + "Shard": "onlineddl_flow", + "RetryMax": 1, + "Tags": ["upgrade_downgrade_onlineddl_flow"] + }, "schemadiff_vrepl": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/schemadiff/vrepl", "-timeout", "30m"], From 113f4c355af659d9eb10042ad446fe06c4a2e4d4 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 5 Jun 2024 11:22:43 +0300 Subject: [PATCH 05/40] Online DDL flow CI: Update golang version to 1.22.4 (#16066) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .github/workflows/upgrade_downgrade_test_onlineddl_flow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml index d05283e482b..c0f6ed9b058 100644 --- a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml +++ b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml @@ -83,7 +83,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@v5 with: - go-version: 1.22.3 + go-version: 1.22.4 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' From 6def78365ddf3875e3b9b7ade4deed18ad248b36 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Wed, 5 Jun 2024 11:08:22 +0200 Subject: [PATCH 06/40] Handle single sharded keyspaces for analysis (#16068) Signed-off-by: Dirkjan Bussink --- go/vt/schemadiff/schema_diff_test.go | 12 +++++++++++- go/vt/vtgate/semantics/analyzer.go | 13 ++++++++----- go/vt/vtgate/semantics/check_invalid.go | 6 ++++-- go/vt/vtgate/semantics/semantic_state.go | 2 +- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/go/vt/schemadiff/schema_diff_test.go b/go/vt/schemadiff/schema_diff_test.go index 270449841d9..3dc1ab291fd 100644 --- a/go/vt/schemadiff/schema_diff_test.go +++ b/go/vt/schemadiff/schema_diff_test.go @@ -414,6 +414,16 @@ func TestSchemaDiff(t *testing.T) { entityOrder: []string{"v2"}, instantCapability: InstantDDLCapabilityIrrelevant, }, + { + name: "add view with over", + toQueries: append( + createQueries, + "create view v2 as SELECT *, ROW_NUMBER() OVER(PARTITION BY info) AS row_num1, ROW_NUMBER() OVER(PARTITION BY info ORDER BY id) AS row_num2 FROM t1;\n", + ), + expectDiffs: 1, + entityOrder: []string{"v2"}, + instantCapability: InstantDDLCapabilityIrrelevant, + }, { name: "add view, alter table", toQueries: []string{ @@ -1050,7 +1060,7 @@ func TestSchemaDiff(t *testing.T) { return } if tc.conflictingDiffs > 0 { - assert.Error(t, err) + require.Error(t, err) impossibleOrderErr, ok := err.(*ImpossibleApplyDiffOrderError) assert.True(t, ok) conflictingDiffsStatements := []string{} diff --git a/go/vt/vtgate/semantics/analyzer.go b/go/vt/vtgate/semantics/analyzer.go index b872a1dde04..c771e541923 100644 --- a/go/vt/vtgate/semantics/analyzer.go +++ b/go/vt/vtgate/semantics/analyzer.go @@ -46,6 +46,7 @@ type analyzer struct { projErr error unshardedErr error warning string + canShortcut bool singleUnshardedKeyspace bool fullAnalysis bool } @@ -135,7 +136,7 @@ func (a *analyzer) newSemTable( comments = commentedStmt.GetParsedComments() } - if a.singleUnshardedKeyspace { + if a.canShortcut { return &SemTable{ Tables: a.earlyTables.Tables, Comments: comments, @@ -386,16 +387,18 @@ func (a *analyzer) reAnalyze(statement sqlparser.SQLNode) error { // canShortCut checks if we are dealing with a single unsharded keyspace and no tables that have managed foreign keys // if so, we can stop the analyzer early func (a *analyzer) canShortCut(statement sqlparser.Statement) (canShortCut bool) { - if a.fullAnalysis { + ks, _ := singleUnshardedKeyspace(a.earlyTables.Tables) + a.singleUnshardedKeyspace = ks != nil + if !a.singleUnshardedKeyspace { return false } - ks, _ := singleUnshardedKeyspace(a.earlyTables.Tables) - if ks == nil { + + if a.fullAnalysis { return false } defer func() { - a.singleUnshardedKeyspace = canShortCut + a.canShortcut = canShortCut }() if !sqlparser.IsDMLStatement(statement) { diff --git a/go/vt/vtgate/semantics/check_invalid.go b/go/vt/vtgate/semantics/check_invalid.go index 2cf16aa0417..272bea9d9d0 100644 --- a/go/vt/vtgate/semantics/check_invalid.go +++ b/go/vt/vtgate/semantics/check_invalid.go @@ -49,11 +49,13 @@ func (a *analyzer) checkForInvalidConstructs(cursor *sqlparser.Cursor) error { return vterrors.VT12001("recursive common table expression") } case *sqlparser.Insert: - if node.Action == sqlparser.ReplaceAct { + if !a.singleUnshardedKeyspace && node.Action == sqlparser.ReplaceAct { return ShardedError{Inner: &UnsupportedConstruct{errString: "REPLACE INTO with sharded keyspace"}} } case *sqlparser.OverClause: - return ShardedError{Inner: &UnsupportedConstruct{errString: "OVER CLAUSE with sharded keyspace"}} + if !a.singleUnshardedKeyspace { + return ShardedError{Inner: &UnsupportedConstruct{errString: "OVER CLAUSE with sharded keyspace"}} + } } return nil diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index f6f62a3eba5..c81442a6c5b 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -821,7 +821,7 @@ func singleUnshardedKeyspace(tableInfos []TableInfo) (ks *vindexes.Keyspace, tab return ks, tables } -// SingleUnshardedKeyspace returns the single keyspace if all tables in the query are in the same keyspace +// SingleKeyspace returns the single keyspace if all tables in the query are in the same keyspace func (st *SemTable) SingleKeyspace() (ks *vindexes.Keyspace) { validKS := func(this *vindexes.Keyspace) bool { if this == nil { From 3fb15b015725e4d2429fd611983f4f60e7694b03 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Thu, 6 Jun 2024 12:23:34 +0200 Subject: [PATCH 07/40] Fix schemadiff semantics handling (#16073) Signed-off-by: Dirkjan Bussink --- go/vt/schemadiff/schema_diff_test.go | 10 ++++++---- go/vt/schemadiff/schema_test.go | 9 +++++++++ go/vt/schemadiff/semantics.go | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/go/vt/schemadiff/schema_diff_test.go b/go/vt/schemadiff/schema_diff_test.go index 3dc1ab291fd..ac3a921acc5 100644 --- a/go/vt/schemadiff/schema_diff_test.go +++ b/go/vt/schemadiff/schema_diff_test.go @@ -415,13 +415,15 @@ func TestSchemaDiff(t *testing.T) { instantCapability: InstantDDLCapabilityIrrelevant, }, { - name: "add view with over", + name: "add view with over and keyword table", toQueries: append( createQueries, - "create view v2 as SELECT *, ROW_NUMBER() OVER(PARTITION BY info) AS row_num1, ROW_NUMBER() OVER(PARTITION BY info ORDER BY id) AS row_num2 FROM t1;\n", + "create table `order` (id int primary key, info int not null);", + "create view v2 as SELECT *, ROW_NUMBER() OVER(PARTITION BY info) AS row_num1, ROW_NUMBER() OVER(PARTITION BY info ORDER BY id) AS row_num2 FROM `order`;", ), - expectDiffs: 1, - entityOrder: []string{"v2"}, + expectDiffs: 2, + expectDeps: 1, + entityOrder: []string{"order", "v2"}, instantCapability: InstantDDLCapabilityIrrelevant, }, { diff --git a/go/vt/schemadiff/schema_test.go b/go/vt/schemadiff/schema_test.go index 7eab685f0d7..23782e676a1 100644 --- a/go/vt/schemadiff/schema_test.go +++ b/go/vt/schemadiff/schema_test.go @@ -125,6 +125,15 @@ func TestNewSchemaFromQueriesUnresolved(t *testing.T) { assert.Equal(t, "CREATE VIEW `v7` AS SELECT * FROM `v8`, `t2`", v.Create().CanonicalStatementString()) } +func TestNewSchemaFromQueriesWithSQLKeyword(t *testing.T) { + queries := []string{ + "create table `order` (id int primary key, info int not null)", + "create view v2 as SELECT *, ROW_NUMBER() OVER(PARTITION BY info) AS row_num1, ROW_NUMBER() OVER(PARTITION BY info ORDER BY id) AS row_num2 FROM `order`;", + } + _, err := NewSchemaFromQueries(NewTestEnv(), queries) + assert.NoError(t, err) +} + func TestNewSchemaFromQueriesUnresolvedAlias(t *testing.T) { // v8 does not exist queries := append(schemaTestCreateQueries, diff --git a/go/vt/schemadiff/semantics.go b/go/vt/schemadiff/semantics.go index ccbf654f566..cbba8c79497 100644 --- a/go/vt/schemadiff/semantics.go +++ b/go/vt/schemadiff/semantics.go @@ -51,7 +51,7 @@ func newDeclarativeSchemaInformation(env *Environment) *declarativeSchemaInforma // FindTableOrVindex implements the SchemaInformation interface func (si *declarativeSchemaInformation) FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, string, topodatapb.TabletType, key.Destination, error) { - table := si.Tables[sqlparser.String(tablename)] + table := si.Tables[tablename.Name.String()] return table, nil, "", 0, nil, nil } From b81c6175d2bb0bfc0d336f4e80bcda16c7826a1b Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 6 Jun 2024 14:47:54 +0300 Subject: [PATCH 08/40] Online DDL: Fail a --in-order-completion migration, if a _prior_ migration within the same context is 'failed' or 'cancelled' (#16071) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../scheduler/onlineddl_scheduler_test.go | 123 ++++++++++++++- go/vt/vttablet/onlineddl/executor.go | 149 +++++++++++++----- go/vt/vttablet/onlineddl/schema.go | 14 ++ 3 files changed, 239 insertions(+), 47 deletions(-) diff --git a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go index 4362069af66..5b88b1f8678 100644 --- a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go +++ b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go @@ -198,7 +198,7 @@ func waitForReadyToComplete(t *testing.T, uuid string, expected bool) { case <-ticker.C: case <-ctx.Done(): } - require.NoError(t, ctx.Err()) + require.NoError(t, ctx.Err(), "waiting for ready_to_complete=%t for %v", expected, uuid) } } @@ -422,6 +422,14 @@ func testScheduler(t *testing.T) { assert.GreaterOrEqual(t, endTime2, endTime1) }) } + testTableCompletionAndStartTimes := func(t *testing.T, uuid1, uuid2 string) { + // expect uuid1 to complete before uuid2 + t.Run("Compare t1, t2 completion times", func(t *testing.T) { + endTime1 := testReadTimestamp(t, uuid1, "completed_timestamp") + startedTime2 := testReadTimestamp(t, uuid2, "started_timestamp") + assert.GreaterOrEqual(t, startedTime2, endTime1) + }) + } testAllowConcurrent := func(t *testing.T, name string, uuid string, expect int64) { t.Run("verify allow_concurrent: "+name, func(t *testing.T) { rs := onlineddl.ReadMigrations(t, &vtParams, uuid) @@ -434,7 +442,7 @@ func testScheduler(t *testing.T) { } // CREATE - t.Run("CREATE TABLEs t1, t1", func(t *testing.T) { + t.Run("CREATE TABLEs t1, t2", func(t *testing.T) { { // The table does not exist t1uuid = testOnlineDDLStatement(t, createParams(createT1Statement, ddlStrategy, "vtgate", "just-created", "", false)) onlineddl.CheckMigrationStatus(t, &vtParams, shards, t1uuid, schema.OnlineDDLStatusComplete) @@ -1183,6 +1191,36 @@ func testScheduler(t *testing.T) { }) }) // in-order-completion + t.Run("in-order-completion: multiple drops for nonexistent tables and views, sequential", func(t *testing.T) { + u, err := schema.CreateOnlineDDLUUID() + require.NoError(t, err) + + sqls := []string{ + fmt.Sprintf("drop table if exists t4_%s", u), + fmt.Sprintf("drop view if exists t1_%s", u), + fmt.Sprintf("drop table if exists t2_%s", u), + fmt.Sprintf("drop view if exists t3_%s", u), + } + sql := strings.Join(sqls, ";") + var vuuids []string + t.Run("drop multiple tables and views, in-order-completion", func(t *testing.T) { + uuidList := testOnlineDDLStatement(t, createParams(sql, ddlStrategy+" --in-order-completion", "vtctl", "", "", true)) // skip wait + vuuids = strings.Split(uuidList, "\n") + assert.Len(t, vuuids, 4) + for _, uuid := range vuuids { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusComplete) + } + }) + require.Len(t, vuuids, 4) + for i := range vuuids { + if i > 0 { + testTableCompletionTimes(t, vuuids[i-1], vuuids[i]) + testTableCompletionAndStartTimes(t, vuuids[i-1], vuuids[i]) + } + } + }) t.Run("in-order-completion: multiple drops for nonexistent tables and views", func(t *testing.T) { u, err := schema.CreateOnlineDDLUUID() require.NoError(t, err) @@ -1198,20 +1236,93 @@ func testScheduler(t *testing.T) { t.Run("drop multiple tables and views, in-order-completion", func(t *testing.T) { uuidList := testOnlineDDLStatement(t, createParams(sql, ddlStrategy+" --allow-concurrent --in-order-completion", "vtctl", "", "", true)) // skip wait vuuids = strings.Split(uuidList, "\n") - assert.Equal(t, 4, len(vuuids)) + assert.Len(t, vuuids, 4) for _, uuid := range vuuids { status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed) fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusComplete) } }) - require.Equal(t, 4, len(vuuids)) + require.Len(t, vuuids, 4) for i := range vuuids { if i > 0 { testTableCompletionTimes(t, vuuids[i-1], vuuids[i]) } } }) + + t.Run("in-order-completion: bail out on first error", func(t *testing.T) { + u, err := schema.CreateOnlineDDLUUID() + require.NoError(t, err) + + sqls := []string{ + fmt.Sprintf("drop table if exists t4_%s", u), + fmt.Sprintf("drop view if exists t1_%s", u), + fmt.Sprintf("drop table t2_%s", u), // non existent + fmt.Sprintf("drop view if exists t3_%s", u), + } + sql := strings.Join(sqls, ";") + var vuuids []string + t.Run("apply schema", func(t *testing.T) { + uuidList := testOnlineDDLStatement(t, createParams(sql, ddlStrategy+" --in-order-completion", "vtctl", "", "", true)) // skip wait + vuuids = strings.Split(uuidList, "\n") + assert.Len(t, vuuids, 4) + for _, uuid := range vuuids[0:2] { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusComplete) + } + { + uuid := vuuids[2] // the failed one + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusFailed) + } + { + uuid := vuuids[3] // should consequently fail without even running + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusQueued, schema.OnlineDDLStatusFailed) + + rs := onlineddl.ReadMigrations(t, &vtParams, uuid) + require.NotNil(t, rs) + for _, row := range rs.Named().Rows { + message := row["message"].ToString() + require.Contains(t, message, vuuids[2]) // Indicating this migration failed due to vuuids[2] failure + } + } + }) + testTableCompletionTimes(t, vuuids[0], vuuids[1]) + testTableCompletionAndStartTimes(t, vuuids[0], vuuids[1]) + testTableCompletionAndStartTimes(t, vuuids[1], vuuids[2]) + }) + t.Run("in-order-completion concurrent: bail out on first error", func(t *testing.T) { + sqls := []string{ + `alter table t1_test force`, + `alter table t2_test force`, + } + sql := strings.Join(sqls, ";") + var vuuids []string + t.Run("apply schema", func(t *testing.T) { + uuidList := testOnlineDDLStatement(t, createParams(sql, ddlStrategy+" --in-order-completion --postpone-completion --allow-concurrent", "vtctl", "", "", true)) // skip wait + vuuids = strings.Split(uuidList, "\n") + assert.Len(t, vuuids, 2) + for _, uuid := range vuuids { + waitForReadyToComplete(t, uuid, true) + } + t.Run("cancel 1st migration", func(t *testing.T) { + onlineddl.CheckCancelMigration(t, &vtParams, shards, vuuids[0], true) + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, vuuids[0], normalWaitTime, schema.OnlineDDLStatusFailed, schema.OnlineDDLStatusCancelled) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, vuuids[0], schema.OnlineDDLStatusCancelled) + }) + t.Run("expect 2nd migration to fail", func(t *testing.T) { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, vuuids[1], normalWaitTime, schema.OnlineDDLStatusFailed, schema.OnlineDDLStatusCancelled) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, vuuids[1], schema.OnlineDDLStatusFailed) + }) + }) + }) t.Run("in-order-completion: two new views, one depends on the other", func(t *testing.T) { u, err := schema.CreateOnlineDDLUUID() require.NoError(t, err) @@ -1225,14 +1336,14 @@ func testScheduler(t *testing.T) { t.Run("create two views, expect both complete", func(t *testing.T) { uuidList := testOnlineDDLStatement(t, createParams(sql, ddlStrategy+" --allow-concurrent --in-order-completion", "vtctl", "", "", true)) // skip wait vuuids = strings.Split(uuidList, "\n") - assert.Equal(t, 2, len(vuuids)) + assert.Len(t, vuuids, 2) for _, uuid := range vuuids { status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed) fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusComplete) } }) - require.Equal(t, 2, len(vuuids)) + require.Len(t, vuuids, 2) testTableCompletionTimes(t, vuuids[0], vuuids[1]) }) t.Run("in-order-completion: new table column, new view depends on said column", func(t *testing.T) { diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index 42b2a4f827b..ebce8f0619c 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -2854,6 +2854,31 @@ func (e *Executor) getCompletedMigrationByContextAndSQL(ctx context.Context, onl return completedUUID, nil } +// readFailedCancelledMigrationsInContextBeforeMigration returns UUIDs for migrations that are failed/cancelled +// and are in the same context as given migration and _precede_ it chronologically (have lower `id` value) +func (e *Executor) readFailedCancelledMigrationsInContextBeforeMigration(ctx context.Context, onlineDDL *schema.OnlineDDL) (uuids []string, err error) { + if onlineDDL.MigrationContext == "" { + // only applies to migrations with an explicit context + return nil, nil + } + query, err := sqlparser.ParseAndBind(sqlSelectFailedCancelledMigrationsInContextBeforeMigration, + sqltypes.StringBindVariable(onlineDDL.MigrationContext), + sqltypes.StringBindVariable(onlineDDL.UUID), + ) + if err != nil { + return nil, err + } + r, err := e.execQuery(ctx, query) + if err != nil { + return uuids, err + } + for _, row := range r.Named().Rows { + uuid := row["migration_uuid"].ToString() + uuids = append(uuids, uuid) + } + return uuids, err +} + // failMigration marks a migration as failed func (e *Executor) failMigration(ctx context.Context, onlineDDL *schema.OnlineDDL, withError error) error { defer e.triggerNextCheckInterval() @@ -2865,6 +2890,23 @@ func (e *Executor) failMigration(ctx context.Context, onlineDDL *schema.OnlineDD return withError } +// validateInOrderMigration checks whether an in-order migration should be forced to fail, either before running or +// while running. +// This may happen if a prior migration in the same context has failed or was cancelled. +func (e *Executor) validateInOrderMigration(ctx context.Context, onlineDDL *schema.OnlineDDL) (wasFailed bool, err error) { + if !onlineDDL.StrategySetting().IsInOrderCompletion() { + return false, nil + } + uuids, err := e.readFailedCancelledMigrationsInContextBeforeMigration(ctx, onlineDDL) + if err != nil { + return false, err + } + if len(uuids) == 0 { + return false, err + } + return true, e.failMigration(ctx, onlineDDL, fmt.Errorf("migration %v cannot run because prior migration %v in same context has failed/was cancelled", onlineDDL.UUID, uuids[0])) +} + // analyzeDropDDLActionMigration analyzes a DROP migration. func (e *Executor) analyzeDropDDLActionMigration(ctx context.Context, onlineDDL *schema.OnlineDDL) error { // Schema analysis: @@ -3384,6 +3426,58 @@ func (e *Executor) executeMigration(ctx context.Context, onlineDDL *schema.Onlin return nil } +// getNonConflictingMigration finds a single 'ready' migration which does not conflict with running migrations. +// Conflicts are: +// - a migration is 'ready' but is not set to run _concurrently_, and there's a running migration that is also non-concurrent +// - a migration is 'ready' but there's another migration 'running' on the exact same table +func (e *Executor) getNonConflictingMigration(ctx context.Context) (*schema.OnlineDDL, error) { + pendingMigrationsUUIDs, err := e.readPendingMigrationsUUIDs(ctx) + if err != nil { + return nil, err + } + r, err := e.execQuery(ctx, sqlSelectReadyMigrations) + if err != nil { + return nil, err + } + for _, row := range r.Named().Rows { + uuid := row["migration_uuid"].ToString() + onlineDDL, migrationRow, err := e.readMigration(ctx, uuid) + if err != nil { + return nil, err + } + isImmediateOperation := migrationRow.AsBool("is_immediate_operation", false) + + if conflictFound, _ := e.isAnyConflictingMigrationRunning(onlineDDL); conflictFound { + continue // this migration conflicts with a running one + } + if e.countOwnedRunningMigrations() >= maxConcurrentOnlineDDLs { + return nil, nil // too many running migrations + } + if isImmediateOperation && onlineDDL.StrategySetting().IsInOrderCompletion() { + // This migration is immediate: if we run it now, it will complete within a second or two at most. + if len(pendingMigrationsUUIDs) > 0 && pendingMigrationsUUIDs[0] != onlineDDL.UUID { + continue + } + } + // We will fail an in-order migration if there's _prior_ migrations within the same migration-context + // which have failed. + if onlineDDL.StrategySetting().IsInOrderCompletion() { + wasFailed, err := e.validateInOrderMigration(ctx, onlineDDL) + if err != nil { + return nil, err + } + if wasFailed { + continue + } + } + // This migration seems good to go + return onlineDDL, err + } + // no non-conflicting migration found... + // Either all ready migrations are conflicting, or there are no ready migrations... + return nil, nil +} + // runNextMigration picks up to one 'ready' migration that is able to run, and executes it. // Possible scenarios: // - no migration is in 'ready' state -- nothing to be done @@ -3405,47 +3499,7 @@ func (e *Executor) runNextMigration(ctx context.Context) error { return nil } - // getNonConflictingMigration finds a single 'ready' migration which does not conflict with running migrations. - // Conflicts are: - // - a migration is 'ready' but is not set to run _concurrently_, and there's a running migration that is also non-concurrent - // - a migration is 'ready' but there's another migration 'running' on the exact same table - getNonConflictingMigration := func() (*schema.OnlineDDL, error) { - pendingMigrationsUUIDs, err := e.readPendingMigrationsUUIDs(ctx) - if err != nil { - return nil, err - } - r, err := e.execQuery(ctx, sqlSelectReadyMigrations) - if err != nil { - return nil, err - } - for _, row := range r.Named().Rows { - uuid := row["migration_uuid"].ToString() - onlineDDL, migrationRow, err := e.readMigration(ctx, uuid) - if err != nil { - return nil, err - } - isImmediateOperation := migrationRow.AsBool("is_immediate_operation", false) - - if conflictFound, _ := e.isAnyConflictingMigrationRunning(onlineDDL); conflictFound { - continue // this migration conflicts with a running one - } - if e.countOwnedRunningMigrations() >= maxConcurrentOnlineDDLs { - continue // too many running migrations - } - if isImmediateOperation && onlineDDL.StrategySetting().IsInOrderCompletion() { - // This migration is immediate: if we run it now, it will complete within a second or two at most. - if len(pendingMigrationsUUIDs) > 0 && pendingMigrationsUUIDs[0] != onlineDDL.UUID { - continue - } - } - // This migration seems good to go - return onlineDDL, err - } - // no non-conflicting migration found... - // Either all ready migrations are conflicting, or there are no ready migrations... - return nil, nil - } - onlineDDL, err := getNonConflictingMigration() + onlineDDL, err := e.getNonConflictingMigration(ctx) if err != nil { return err } @@ -3792,6 +3846,19 @@ func (e *Executor) reviewRunningMigrations(ctx context.Context) (countRunnning i _ = e.updateMigrationETASecondsByProgress(ctx, uuid) _ = e.updateMigrationLastThrottled(ctx, uuid, time.Unix(s.timeThrottled, 0), s.componentThrottled) + if onlineDDL.StrategySetting().IsInOrderCompletion() { + // We will fail an in-order migration if there's _prior_ migrations within the same migration-context + // which have failed. + wasFailed, err := e.validateInOrderMigration(ctx, onlineDDL) + if err != nil { + return err + } + if wasFailed { + return nil + } + } + + // Check if the migration is ready to cut-over, and proceed to do so if it is. isReady, err := e.isVReplMigrationReadyToCutOver(ctx, onlineDDL, s) if err != nil { _ = e.updateMigrationMessage(ctx, uuid, err.Error()) diff --git a/go/vt/vttablet/onlineddl/schema.go b/go/vt/vttablet/onlineddl/schema.go index 2ba566703e5..30f132bd0e3 100644 --- a/go/vt/vttablet/onlineddl/schema.go +++ b/go/vt/vttablet/onlineddl/schema.go @@ -303,6 +303,7 @@ const ( FROM _vt.schema_migrations WHERE migration_status='running' + ORDER BY id ` sqlSelectCompleteMigrationsOnTable = `SELECT migration_uuid, @@ -333,6 +334,18 @@ const ( WHERE migration_status='running' AND liveness_timestamp < NOW() - INTERVAL %a MINUTE + ORDER BY id + ` + sqlSelectFailedCancelledMigrationsInContextBeforeMigration = `SELECT + migration_uuid + FROM _vt.schema_migrations + WHERE + migration_context=%a + AND migration_status IN ('failed', 'cancelled') + AND id < ( + SELECT id FROM _vt.schema_migrations WHERE migration_uuid=%a + ) + ORDER BY id ` sqlSelectPendingMigrations = `SELECT migration_uuid, @@ -365,6 +378,7 @@ const ( NOW() - INTERVAL %a SECOND, NOW() - INTERVAL retain_artifacts_seconds SECOND ) + ORDER BY id ` sqlFixCompletedTimestamp = `UPDATE _vt.schema_migrations SET From 307b290a356644aad1b5a2135e22be92b258ef4e Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 6 Jun 2024 17:08:51 +0300 Subject: [PATCH 09/40] Changelog 20.0: Fix broken links (#16048) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- changelog/20.0/20.0.0/summary.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog/20.0/20.0.0/summary.md b/changelog/20.0/20.0.0/summary.md index 27016536815..6e09cc982ef 100644 --- a/changelog/20.0/20.0.0/summary.md +++ b/changelog/20.0/20.0.0/summary.md @@ -183,7 +183,7 @@ This makes reparenting in Vitess resilient to client errors, and prevents Planne In order to preserve the old behaviour, the users can set the flag back to `0 seconds` causing open transactions to never be shutdown, but in that case, they run the risk of PlannedReparentShard calls timing out. -#### New `unmanaged` Flag and `disable_active_reparents` deprecation +#### New `unmanaged` Flag and `disable_active_reparents` deprecation New flag `--unmanaged` has been introduced in this release to make it easier to flag unmanaged tablets. It also runs validations to make sure the unmanaged tablets are configured properly. `--disable_active_reparents` flag has been deprecated for `vttablet`, `vtcombo` and `vttestserver` binaries and will be removed in future releases. Specifying the `--unmanaged` flag will also block replication commands and replication repairs. @@ -338,7 +338,7 @@ VTTablet exposes two new counter stats: * `QueryCacheHits`: Query engine query cache hits * `QueryCacheMisses`: Query engine query cache misses -### VTTablet Query Text Characters Processed +### VTTablet Query Text Characters Processed VTGate and VTTablet expose a new counter stat `QueryTextCharactersProcessed` to reflect the number of query text characters processed. From 87ecae7de905e2bccedb9d26ed3d4a34e76d4d8e Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 6 Jun 2024 17:11:40 +0300 Subject: [PATCH 10/40] `schemadiff`: adding a FK dependency unit test (#16069) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/schemadiff/schema_diff_test.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/go/vt/schemadiff/schema_diff_test.go b/go/vt/schemadiff/schema_diff_test.go index ac3a921acc5..4d6ca522d1e 100644 --- a/go/vt/schemadiff/schema_diff_test.go +++ b/go/vt/schemadiff/schema_diff_test.go @@ -979,6 +979,22 @@ func TestSchemaDiff(t *testing.T) { conflictingDiffs: 2, instantCapability: InstantDDLCapabilityImpossible, }, + { + name: "add and drop FK, add and drop respective tables", + fromQueries: []string{ + "create table t1 (id int primary key, p int, key p_idx (p));", + "create table t2 (id int primary key, p int, key p_idx (p), foreign key (p) references t1 (p) on delete no action);", + }, + toQueries: []string{ + "create table t2 (id int primary key, p int, key p_idx (p), foreign key (p) references t3 (p) on delete no action);", + "create table t3 (id int primary key, p int, key p_idx (p));", + }, + expectDiffs: 3, + expectDeps: 2, // [alter t2]/[drop t1], [alter t2]/[create t3] + sequential: true, + entityOrder: []string{"t3", "t2", "t1"}, + instantCapability: InstantDDLCapabilityImpossible, + }, { name: "two identical foreign keys in table, drop one", fromQueries: []string{ @@ -1053,7 +1069,7 @@ func TestSchemaDiff(t *testing.T) { for _, dep := range deps { depsKeys = append(depsKeys, dep.hashKey()) } - assert.Equalf(t, tc.expectDeps, len(deps), "found deps: %v", depsKeys) + assert.Equalf(t, tc.expectDeps, len(deps), "found %v deps: %v", len(depsKeys), depsKeys) assert.Equal(t, tc.sequential, schemaDiff.HasSequentialExecutionDependencies()) orderedDiffs, err := schemaDiff.OrderedDiffs(ctx) From f643006786822ecd10fba1b4cbc09ffa2cefb243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Mon, 10 Jun 2024 09:18:45 +0200 Subject: [PATCH 11/40] refactor: cleaner cloning API (#16079) Signed-off-by: Andres Taylor --- .../vtgate/queries/random/query_gen.go | 2 +- go/test/fuzzing/ast_fuzzer.go | 2 +- go/vt/schema/online_ddl.go | 2 +- go/vt/schemadiff/capability.go | 2 +- go/vt/schemadiff/schema.go | 10 +++---- go/vt/schemadiff/table.go | 14 +++++----- go/vt/schemadiff/view.go | 8 +++--- go/vt/sqlparser/ast_funcs.go | 5 ++++ go/vt/vtgate/executor.go | 2 +- go/vt/vtgate/planbuilder/ddl.go | 2 +- .../operators/aggregation_pushing.go | 2 +- .../operators/aggregation_pushing_helper.go | 4 +-- go/vt/vtgate/planbuilder/operators/delete.go | 4 +-- go/vt/vtgate/planbuilder/operators/horizon.go | 2 +- go/vt/vtgate/planbuilder/operators/insert.go | 2 +- go/vt/vtgate/planbuilder/operators/limit.go | 2 +- go/vt/vtgate/planbuilder/operators/phases.go | 4 +-- .../planbuilder/operators/projection.go | 2 +- .../operators/projection_pushing.go | 2 +- .../planbuilder/operators/query_planning.go | 4 +-- .../planbuilder/operators/querygraph.go | 4 +-- .../vtgate/planbuilder/operators/subquery.go | 2 +- .../planbuilder/operators/subquery_builder.go | 2 +- go/vt/vtgate/planbuilder/operators/table.go | 2 +- go/vt/vtgate/planbuilder/operators/update.go | 4 +-- go/vt/vtgate/planbuilder/operators/upsert.go | 2 +- go/vt/vtgate/planbuilder/simplifier_test.go | 4 +-- go/vt/vtgate/semantics/early_rewriter.go | 2 +- go/vt/vtgate/semantics/semantic_state.go | 2 +- .../simplifier/expression_simplifier.go | 8 +++--- go/vt/vtgate/simplifier/simplifier.go | 28 +++++++++---------- go/vt/vtgate/vindexes/vschema.go | 2 +- go/vt/vtgate/vschema_manager.go | 2 +- go/vt/vttablet/onlineddl/executor.go | 6 ++-- 34 files changed, 76 insertions(+), 71 deletions(-) diff --git a/go/test/endtoend/vtgate/queries/random/query_gen.go b/go/test/endtoend/vtgate/queries/random/query_gen.go index b078f1cab8b..ba7c83aaa91 100644 --- a/go/test/endtoend/vtgate/queries/random/query_gen.go +++ b/go/test/endtoend/vtgate/queries/random/query_gen.go @@ -132,7 +132,7 @@ func (t *tableT) addColumns(col ...column) { func (t *tableT) clone() *tableT { return &tableT{ - tableExpr: sqlparser.CloneSimpleTableExpr(t.tableExpr), + tableExpr: sqlparser.Clone(t.tableExpr), alias: t.alias, cols: slices.Clone(t.cols), } diff --git a/go/test/fuzzing/ast_fuzzer.go b/go/test/fuzzing/ast_fuzzer.go index 5951a0da9eb..278b20df588 100644 --- a/go/test/fuzzing/ast_fuzzer.go +++ b/go/test/fuzzing/ast_fuzzer.go @@ -61,7 +61,7 @@ func FuzzEqualsSQLNode(data []byte) int { } // Target 2: - newSQLNode := sqlparser.CloneSQLNode(inA) + newSQLNode := sqlparser.Clone(inA) if !sqlparser.EqualsSQLNode(inA, newSQLNode) { panic("These two nodes should be identical") } diff --git a/go/vt/schema/online_ddl.go b/go/vt/schema/online_ddl.go index 57ed075cf38..7b8647f86b7 100644 --- a/go/vt/schema/online_ddl.go +++ b/go/vt/schema/online_ddl.go @@ -288,7 +288,7 @@ func OnlineDDLFromCommentedStatement(stmt sqlparser.Statement) (onlineDDL *Onlin // We clone the comments because they will end up being cached by the query planner. Then, the Directive() function actually modifies the comments. // If comments are shared in cache, and Directive() modifies it, then we have a concurrency issue when someone else wants to read the comments. // By cloning the comments we remove the concurrency problem. - comments = sqlparser.CloneRefOfParsedComments(comments) + comments = sqlparser.Clone(comments) comments.ResetDirectives() if comments.Length() == 0 { diff --git a/go/vt/schemadiff/capability.go b/go/vt/schemadiff/capability.go index 9ce985c71d9..cde99ac18c3 100644 --- a/go/vt/schemadiff/capability.go +++ b/go/vt/schemadiff/capability.go @@ -74,7 +74,7 @@ func alterOptionCapableOfInstantDDL(alterOption sqlparser.AlterOption, createTab return true, col.Type.Options.Storage } colStringStrippedDown := func(col *sqlparser.ColumnDefinition, stripDefault bool, stripEnum bool) string { - strippedCol := sqlparser.CloneRefOfColumnDefinition(col) + strippedCol := sqlparser.Clone(col) if stripDefault { strippedCol.Type.Options.Default = nil strippedCol.Type.Options.DefaultLiteral = false diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index efad76d9a33..f4cc0b67217 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -1014,7 +1014,7 @@ func (s *Schema) ValidateViewReferences() error { schemaInformation.addTable("dual") for _, view := range s.Views() { - sel := sqlparser.CloneSelectStatement(view.CreateView.Select) // Analyze(), below, rewrites the select; we don't want to actually modify the schema + sel := sqlparser.Clone(view.CreateView.Select) // Analyze(), below, rewrites the select; we don't want to actually modify the schema _, err := semantics.AnalyzeStrict(sel, semanticKS.Name, schemaInformation) formalizeErr := func(err error) error { if err == nil { @@ -1079,8 +1079,8 @@ func (s *Schema) getViewColumnNames(v *CreateViewEntity, schemaInformation *decl case *sqlparser.StarExpr: if tableName := node.TableName.Name.String(); tableName != "" { for _, col := range schemaInformation.Tables[tableName].Columns { - name := sqlparser.CloneRefOfIdentifierCI(&col.Name) - columnNames = append(columnNames, name) + name := sqlparser.Clone(col.Name) + columnNames = append(columnNames, &name) } } else { dependentNames := getViewDependentTableNames(v.CreateView) @@ -1088,8 +1088,8 @@ func (s *Schema) getViewColumnNames(v *CreateViewEntity, schemaInformation *decl for _, entityName := range dependentNames { if schemaInformation.Tables[entityName] != nil { // is nil for dual/DUAL for _, col := range schemaInformation.Tables[entityName].Columns { - name := sqlparser.CloneRefOfIdentifierCI(&col.Name) - columnNames = append(columnNames, name) + name := sqlparser.Clone(col.Name) + columnNames = append(columnNames, &name) } } } diff --git a/go/vt/schemadiff/table.go b/go/vt/schemadiff/table.go index def83fa7f19..5d21d524704 100644 --- a/go/vt/schemadiff/table.go +++ b/go/vt/schemadiff/table.go @@ -146,7 +146,7 @@ func (d *AlterTableEntityDiff) Clone() EntityDiff { } ann := *d.annotations clone := &AlterTableEntityDiff{ - alterTable: sqlparser.CloneRefOfAlterTable(d.alterTable), + alterTable: sqlparser.Clone(d.alterTable), instantDDLCapability: d.instantDDLCapability, annotations: &ann, } @@ -245,7 +245,7 @@ func (d *CreateTableEntityDiff) Clone() EntityDiff { return nil } clone := &CreateTableEntityDiff{ - createTable: sqlparser.CloneRefOfCreateTable(d.createTable), + createTable: sqlparser.Clone(d.createTable), } if d.to != nil { clone.to = d.to.Clone().(*CreateTableEntity) @@ -336,7 +336,7 @@ func (d *DropTableEntityDiff) Clone() EntityDiff { return nil } clone := &DropTableEntityDiff{ - dropTable: sqlparser.CloneRefOfDropTable(d.dropTable), + dropTable: sqlparser.Clone(d.dropTable), } if d.from != nil { clone.from = d.from.Clone().(*CreateTableEntity) @@ -428,7 +428,7 @@ func (d *RenameTableEntityDiff) Clone() EntityDiff { return nil } clone := &RenameTableEntityDiff{ - renameTable: sqlparser.CloneRefOfRenameTable(d.renameTable), + renameTable: sqlparser.Clone(d.renameTable), } if d.from != nil { clone.from = d.from.Clone().(*CreateTableEntity) @@ -526,7 +526,7 @@ func (c *CreateTableEntity) GetCollation() string { } func (c *CreateTableEntity) Clone() Entity { - return &CreateTableEntity{CreateTable: sqlparser.CloneRefOfCreateTable(c.CreateTable), Env: c.Env} + return &CreateTableEntity{CreateTable: sqlparser.Clone(c.CreateTable), Env: c.Env} } func getTableCharsetCollate(env *Environment, tableOptions *sqlparser.TableOptions) *charsetCollate { @@ -1601,8 +1601,8 @@ func (c *CreateTableEntity) diffKeys(alterTable *sqlparser.AlterTable, // Returns if this is a visibility only change and if true, whether // the new visibility is invisible or not. func indexOnlyVisibilityChange(t1Key, t2Key *sqlparser.IndexDefinition) (bool, bool) { - t1KeyCopy := sqlparser.CloneRefOfIndexDefinition(t1Key) - t2KeyCopy := sqlparser.CloneRefOfIndexDefinition(t2Key) + t1KeyCopy := sqlparser.Clone(t1Key) + t2KeyCopy := sqlparser.Clone(t2Key) t1KeyKeptOptions := make([]*sqlparser.IndexOption, 0, len(t1KeyCopy.Options)) t2KeyInvisible := false for _, opt := range t1KeyCopy.Options { diff --git a/go/vt/schemadiff/view.go b/go/vt/schemadiff/view.go index c4d48ac66cc..d2dc4dfb76f 100644 --- a/go/vt/schemadiff/view.go +++ b/go/vt/schemadiff/view.go @@ -106,7 +106,7 @@ func (d *AlterViewEntityDiff) Clone() EntityDiff { return nil } clone := &AlterViewEntityDiff{ - alterView: sqlparser.CloneRefOfAlterView(d.alterView), + alterView: sqlparser.Clone(d.alterView), } if d.from != nil { clone.from = d.from.Clone().(*CreateViewEntity) @@ -200,7 +200,7 @@ func (d *CreateViewEntityDiff) Clone() EntityDiff { return nil } return &CreateViewEntityDiff{ - createView: sqlparser.CloneRefOfCreateView(d.createView), + createView: sqlparser.Clone(d.createView), } } @@ -287,7 +287,7 @@ func (d *DropViewEntityDiff) Clone() EntityDiff { return nil } clone := &DropViewEntityDiff{ - dropView: sqlparser.CloneRefOfDropView(d.dropView), + dropView: sqlparser.Clone(d.dropView), } if d.from != nil { clone.from = d.from.Clone().(*CreateViewEntity) @@ -402,7 +402,7 @@ func (c *CreateViewEntity) Apply(diff EntityDiff) (Entity, error) { } func (c *CreateViewEntity) Clone() Entity { - return &CreateViewEntity{CreateView: sqlparser.CloneRefOfCreateView(c.CreateView)} + return &CreateViewEntity{CreateView: sqlparser.Clone(c.CreateView)} } func (c *CreateViewEntity) identicalOtherThanName(other *CreateViewEntity) bool { diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index df201676fae..df419e5d7a1 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -2776,3 +2776,8 @@ func (lock Lock) GetHighestOrderLock(newLock Lock) Lock { } return lock } + +// Clone returns a deep copy of the SQLNode, typed as the original type +func Clone[K SQLNode](x K) K { + return CloneSQLNode(x).(K) +} diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index 2679cf5a2fd..cec0dba8274 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -1592,7 +1592,7 @@ func (e *Executor) planPrepareStmt(ctx context.Context, vcursor *vcursorImpl, qu ctx, vcursor, query, - sqlparser.CloneStatement(stmt), + sqlparser.Clone(stmt), vcursor.marginComments, map[string]*querypb.BindVariable{}, reservedVars, /* normalize */ diff --git a/go/vt/vtgate/planbuilder/ddl.go b/go/vt/vtgate/planbuilder/ddl.go index 351bf42672c..4c4b3791c20 100644 --- a/go/vt/vtgate/planbuilder/ddl.go +++ b/go/vt/vtgate/planbuilder/ddl.go @@ -210,7 +210,7 @@ func buildCreateViewCommon( // because we don't trust the schema tracker to have up-to-date info, we don't want to expand any SELECT * here var expressions []sqlparser.SelectExprs _ = sqlparser.VisitAllSelects(ddlSelect, func(p *sqlparser.Select, idx int) error { - expressions = append(expressions, sqlparser.CloneSelectExprs(p.SelectExprs)) + expressions = append(expressions, sqlparser.Clone(p.SelectExprs)) return nil }) selectPlan, err := createInstructionFor(ctx, sqlparser.String(ddlSelect), ddlSelect, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) diff --git a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go index 43a88d82871..67dd0c1d306 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go +++ b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go @@ -628,7 +628,7 @@ func splitAvgAggregations(ctx *plancontext.PlanningContext, aggr *Aggregator) (O outputColumn := aeWrap(col.Expr) outputColumn.As = sqlparser.NewIdentifierCI(col.ColumnName()) - proj.addUnexploredExpr(sqlparser.CloneRefOfAliasedExpr(col), calcExpr) + proj.addUnexploredExpr(sqlparser.Clone(col), calcExpr) col.Expr = sumExpr found := false for aggrOffset, aggregation := range aggr.Aggregations { diff --git a/go/vt/vtgate/planbuilder/operators/aggregation_pushing_helper.go b/go/vt/vtgate/planbuilder/operators/aggregation_pushing_helper.go index eb14f83b7df..2c47f426695 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregation_pushing_helper.go +++ b/go/vt/vtgate/planbuilder/operators/aggregation_pushing_helper.go @@ -266,7 +266,7 @@ func (p *joinPusher) countStar(ctx *plancontext.PlanningContext) (*sqlparser.Ali // It returns the expression of the aggregation as it should be used in the parent Aggregator. func (p *joinPusher) addAggr(ctx *plancontext.PlanningContext, aggr Aggr) sqlparser.Expr { copyAggr := aggr - expr := sqlparser.CloneExpr(aggr.Original.Expr) + expr := sqlparser.Clone(aggr.Original.Expr) copyAggr.Original = aeWrap(expr) // copy dependencies so we can keep track of which side expressions need to be pushed to ctx.SemTable.Direct[expr] = p.tableID @@ -291,7 +291,7 @@ func (p *joinPusher) pushThroughAggr(aggr Aggr) { // It returns the expression of the GroupBy as it should be used in the parent Aggregator. func (p *joinPusher) addGrouping(ctx *plancontext.PlanningContext, gb GroupBy) sqlparser.Expr { copyGB := gb - expr := sqlparser.CloneExpr(gb.Inner) + expr := sqlparser.Clone(gb.Inner) // copy dependencies so we can keep track of which side expressions need to be pushed to ctx.SemTable.CopyDependencies(gb.Inner, expr) // if the column exists in the selection then copy it down to the pushed aggregator operator. diff --git a/go/vt/vtgate/planbuilder/operators/delete.go b/go/vt/vtgate/planbuilder/operators/delete.go index a3c45e79135..5bbf5218bd7 100644 --- a/go/vt/vtgate/planbuilder/operators/delete.go +++ b/go/vt/vtgate/planbuilder/operators/delete.go @@ -73,7 +73,7 @@ func createOperatorFromDelete(ctx *plancontext.PlanningContext, deleteStmt *sqlp return createDeleteWithInputOp(ctx, deleteStmt) } - delClone := sqlparser.CloneRefOfDelete(deleteStmt) + delClone := sqlparser.Clone(deleteStmt) var vTbl *vindexes.Table op, vTbl = createDeleteOperator(ctx, deleteStmt) @@ -315,7 +315,7 @@ func addOrdering(ctx *plancontext.PlanningContext, orderBy sqlparser.OrderBy, op continue } ordering.Order = append(ordering.Order, OrderBy{ - Inner: sqlparser.CloneRefOfOrder(order), + Inner: sqlparser.Clone(order), SimplifiedExpr: order.Expr, }) } diff --git a/go/vt/vtgate/planbuilder/operators/horizon.go b/go/vt/vtgate/planbuilder/operators/horizon.go index 532441d6a34..c28bc2dd5f0 100644 --- a/go/vt/vtgate/planbuilder/operators/horizon.go +++ b/go/vt/vtgate/planbuilder/operators/horizon.go @@ -59,7 +59,7 @@ func newHorizon(src Operator, query sqlparser.SelectStatement) *Horizon { func (h *Horizon) Clone(inputs []Operator) Operator { klone := *h klone.Source = inputs[0] - klone.ColumnAliases = sqlparser.CloneColumns(h.ColumnAliases) + klone.ColumnAliases = sqlparser.Clone(h.ColumnAliases) klone.Columns = slices.Clone(h.Columns) klone.ColumnsOffset = slices.Clone(h.ColumnsOffset) klone.QP = h.QP diff --git a/go/vt/vtgate/planbuilder/operators/insert.go b/go/vt/vtgate/planbuilder/operators/insert.go index 7c6e242ae9c..a009e14f99c 100644 --- a/go/vt/vtgate/planbuilder/operators/insert.go +++ b/go/vt/vtgate/planbuilder/operators/insert.go @@ -135,7 +135,7 @@ func createOperatorFromInsert(ctx *plancontext.PlanningContext, ins *sqlparser.I delStmt := &sqlparser.Delete{ Comments: ins.Comments, - TableExprs: sqlparser.TableExprs{sqlparser.CloneRefOfAliasedTableExpr(ins.Table)}, + TableExprs: sqlparser.TableExprs{sqlparser.Clone(ins.Table)}, Where: sqlparser.NewWhere(sqlparser.WhereClause, whereExpr), } delOp := createOpFromStmt(ctx, delStmt, false, "") diff --git a/go/vt/vtgate/planbuilder/operators/limit.go b/go/vt/vtgate/planbuilder/operators/limit.go index 0d4857d5aaa..1801e57c1c9 100644 --- a/go/vt/vtgate/planbuilder/operators/limit.go +++ b/go/vt/vtgate/planbuilder/operators/limit.go @@ -36,7 +36,7 @@ type Limit struct { func (l *Limit) Clone(inputs []Operator) Operator { return &Limit{ Source: inputs[0], - AST: sqlparser.CloneRefOfLimit(l.AST), + AST: sqlparser.Clone(l.AST), Top: l.Top, Pushed: l.Pushed, } diff --git a/go/vt/vtgate/planbuilder/operators/phases.go b/go/vt/vtgate/planbuilder/operators/phases.go index 3864b514aa9..9f2178bae05 100644 --- a/go/vt/vtgate/planbuilder/operators/phases.go +++ b/go/vt/vtgate/planbuilder/operators/phases.go @@ -176,8 +176,8 @@ func createDMLWithInput(ctx *plancontext.PlanningContext, op, src Operator, in * targetQT := targetTable.QTable qt := &QueryTable{ ID: targetQT.ID, - Alias: sqlparser.CloneRefOfAliasedTableExpr(targetQT.Alias), - Table: sqlparser.CloneTableName(targetQT.Table), + Alias: sqlparser.Clone(targetQT.Alias), + Table: sqlparser.Clone(targetQT.Table), Predicates: []sqlparser.Expr{compExpr}, } diff --git a/go/vt/vtgate/planbuilder/operators/projection.go b/go/vt/vtgate/planbuilder/operators/projection.go index 41b83c8f7fe..869cacc005a 100644 --- a/go/vt/vtgate/planbuilder/operators/projection.go +++ b/go/vt/vtgate/planbuilder/operators/projection.go @@ -111,7 +111,7 @@ type ( func newProjExpr(ae *sqlparser.AliasedExpr) *ProjExpr { return &ProjExpr{ - Original: sqlparser.CloneRefOfAliasedExpr(ae), + Original: sqlparser.Clone(ae), EvalExpr: ae.Expr, ColExpr: ae.Expr, } diff --git a/go/vt/vtgate/planbuilder/operators/projection_pushing.go b/go/vt/vtgate/planbuilder/operators/projection_pushing.go index 56f829fc7f5..d1baf6def62 100644 --- a/go/vt/vtgate/planbuilder/operators/projection_pushing.go +++ b/go/vt/vtgate/planbuilder/operators/projection_pushing.go @@ -327,7 +327,7 @@ func splitUnexploredExpression( alias string, dt *DerivedTable, ) applyJoinColumn { - original := sqlparser.CloneRefOfAliasedExpr(pe.Original) + original := sqlparser.Clone(pe.Original) expr := pe.ColExpr var colName *sqlparser.ColName diff --git a/go/vt/vtgate/planbuilder/operators/query_planning.go b/go/vt/vtgate/planbuilder/operators/query_planning.go index f2625bcb90b..b20cad7c125 100644 --- a/go/vt/vtgate/planbuilder/operators/query_planning.go +++ b/go/vt/vtgate/planbuilder/operators/query_planning.go @@ -34,7 +34,7 @@ func planQuery(ctx *plancontext.PlanningContext, root Operator) Operator { var selExpr sqlparser.SelectExprs if horizon, isHorizon := root.(*Horizon); isHorizon { sel := sqlparser.GetFirstSelect(horizon.Query) - selExpr = sqlparser.CloneSelectExprs(sel.SelectExprs) + selExpr = sqlparser.Clone(sel.SelectExprs) } output := runPhases(ctx, root) @@ -252,7 +252,7 @@ func tryPushLimit(ctx *plancontext.PlanningContext, in *Limit) (Operator, *Apply } func createPushedLimit(ctx *plancontext.PlanningContext, src Operator, orig *Limit) Operator { - pushedLimit := sqlparser.CloneRefOfLimit(orig.AST) + pushedLimit := sqlparser.Clone(orig.AST) if pushedLimit.Offset != nil { // we can't push down an offset, so we need to convert it to a rowcount // by adding it to the already existing rowcount, and then let the LIMIT running on the vtgate do the rest diff --git a/go/vt/vtgate/planbuilder/operators/querygraph.go b/go/vt/vtgate/planbuilder/operators/querygraph.go index bc731f29df6..8e8572f7dfa 100644 --- a/go/vt/vtgate/planbuilder/operators/querygraph.go +++ b/go/vt/vtgate/planbuilder/operators/querygraph.go @@ -190,8 +190,8 @@ func (qg *QueryGraph) AddPredicate(ctx *plancontext.PlanningContext, expr sqlpar func (qt *QueryTable) Clone() *QueryTable { return &QueryTable{ ID: qt.ID, - Alias: sqlparser.CloneRefOfAliasedTableExpr(qt.Alias), - Table: sqlparser.CloneTableName(qt.Table), + Alias: sqlparser.Clone(qt.Alias), + Table: sqlparser.Clone(qt.Table), Predicates: qt.Predicates, IsInfSchema: qt.IsInfSchema, } diff --git a/go/vt/vtgate/planbuilder/operators/subquery.go b/go/vt/vtgate/planbuilder/operators/subquery.go index 03a482185d8..e2f046f4a4d 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery.go +++ b/go/vt/vtgate/planbuilder/operators/subquery.go @@ -124,7 +124,7 @@ func (sq *SubQuery) Clone(inputs []Operator) Operator { } klone.JoinColumns = slices.Clone(sq.JoinColumns) klone.Vars = maps.Clone(sq.Vars) - klone.Predicates = sqlparser.CloneExprs(sq.Predicates) + klone.Predicates = sqlparser.Clone(sq.Predicates) return &klone } diff --git a/go/vt/vtgate/planbuilder/operators/subquery_builder.go b/go/vt/vtgate/planbuilder/operators/subquery_builder.go index 4caf3530075..f2fdefeb007 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_builder.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_builder.go @@ -297,7 +297,7 @@ func (sqb *SubQueryBuilder) pullOutValueSubqueries( outerID semantics.TableSet, isDML bool, ) (sqlparser.Expr, []*SubQuery) { - original := sqlparser.CloneExpr(expr) + original := sqlparser.Clone(expr) sqe := extractSubQueries(ctx, expr, isDML) if sqe == nil { return nil, nil diff --git a/go/vt/vtgate/planbuilder/operators/table.go b/go/vt/vtgate/planbuilder/operators/table.go index 14207fe3b3e..3ecd4982ece 100644 --- a/go/vt/vtgate/planbuilder/operators/table.go +++ b/go/vt/vtgate/planbuilder/operators/table.go @@ -45,7 +45,7 @@ type ( func (to *Table) Clone([]Operator) Operator { var columns []*sqlparser.ColName for _, name := range to.Columns { - columns = append(columns, sqlparser.CloneRefOfColName(name)) + columns = append(columns, sqlparser.Clone(name)) } return &Table{ QTable: to.QTable, diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index 4abf319ad08..ba83ad7efaf 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -338,7 +338,7 @@ func createUpdateOperator(ctx *plancontext.PlanningContext, updStmt *sqlparser.U // updClone is used in foreign key planning to create the selection statements to be used for verification and selection. // If we encounter subqueries, we want to fix the updClone to use the replaced expression, so that the pulled out subquery's // result is used everywhere instead of running the subquery multiple times, which is wasteful. - updClone := sqlparser.CloneRefOfUpdate(updStmt) + updClone := sqlparser.Clone(updStmt) var tblInfo semantics.TableInfo var err error for idx, updExpr := range updStmt.Exprs { @@ -346,7 +346,7 @@ func createUpdateOperator(ctx *plancontext.PlanningContext, updStmt *sqlparser.U if len(subqs) == 0 { expr = updExpr.Expr } else { - updClone.Exprs[idx].Expr = sqlparser.CloneExpr(expr) + updClone.Exprs[idx].Expr = sqlparser.Clone(expr) ctx.SemTable.UpdateChildFKExpr(updExpr, expr) } proj := newProjExpr(aeWrap(expr)) diff --git a/go/vt/vtgate/planbuilder/operators/upsert.go b/go/vt/vtgate/planbuilder/operators/upsert.go index 8f028a790b2..bfe2a1cbc52 100644 --- a/go/vt/vtgate/planbuilder/operators/upsert.go +++ b/go/vt/vtgate/planbuilder/operators/upsert.go @@ -129,7 +129,7 @@ func createUpsertOperator(ctx *plancontext.PlanningContext, ins *sqlparser.Inser updOp := createOpFromStmt(ctx, upd, false, "") // replan insert statement without on duplicate key update. - newInsert := sqlparser.CloneRefOfInsert(ins) + newInsert := sqlparser.Clone(ins) newInsert.OnDup = nil newInsert.Rows = sqlparser.Values{row} insOp = createOpFromStmt(ctx, newInsert, false, "") diff --git a/go/vt/vtgate/planbuilder/simplifier_test.go b/go/vt/vtgate/planbuilder/simplifier_test.go index 61ed220bd44..305c18896e3 100644 --- a/go/vt/vtgate/planbuilder/simplifier_test.go +++ b/go/vt/vtgate/planbuilder/simplifier_test.go @@ -45,7 +45,7 @@ func TestSimplifyBuggyQuery(t *testing.T) { } stmt, reserved, err := sqlparser.NewTestParser().Parse2(query) require.NoError(t, err) - rewritten, _ := sqlparser.RewriteAST(sqlparser.CloneStatement(stmt), vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil, nil) + rewritten, _ := sqlparser.RewriteAST(sqlparser.Clone(stmt), vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil, nil) reservedVars := sqlparser.NewReservedVars("vtg", reserved) simplified := simplifier.SimplifyStatement( @@ -68,7 +68,7 @@ func TestSimplifyPanic(t *testing.T) { } stmt, reserved, err := sqlparser.NewTestParser().Parse2(query) require.NoError(t, err) - rewritten, _ := sqlparser.RewriteAST(sqlparser.CloneStatement(stmt), vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil, nil) + rewritten, _ := sqlparser.RewriteAST(sqlparser.Clone(stmt), vschema.CurrentDb(), sqlparser.SQLSelectLimitUnset, "", nil, nil, nil) reservedVars := sqlparser.NewReservedVars("vtg", reserved) simplified := simplifier.SimplifyStatement( diff --git a/go/vt/vtgate/semantics/early_rewriter.go b/go/vt/vtgate/semantics/early_rewriter.go index 51ed110adf9..568e1900d44 100644 --- a/go/vt/vtgate/semantics/early_rewriter.go +++ b/go/vt/vtgate/semantics/early_rewriter.go @@ -493,7 +493,7 @@ func (r *earlyRewriter) rewriteAliasesInGroupBy(node sqlparser.Expr, sel *sqlpar return } - cursor.Replace(sqlparser.CloneExpr(item.expr)) + cursor.Replace(sqlparser.Clone(item.expr)) } }, nil) diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index c81442a6c5b..bedb9105116 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -966,7 +966,7 @@ func (st *SemTable) Clone(n sqlparser.SQLNode) sqlparser.SQLNode { if !isExpr { return } - cursor.Replace(sqlparser.CloneExpr(expr)) + cursor.Replace(sqlparser.Clone(expr)) }, st.CopySemanticInfo) } diff --git a/go/vt/vtgate/simplifier/expression_simplifier.go b/go/vt/vtgate/simplifier/expression_simplifier.go index 86e3471baea..b64402cfaac 100644 --- a/go/vt/vtgate/simplifier/expression_simplifier.go +++ b/go/vt/vtgate/simplifier/expression_simplifier.go @@ -29,14 +29,14 @@ type CheckF = func(sqlparser.Expr) bool func SimplifyExpr(in sqlparser.Expr, test CheckF) sqlparser.Expr { // since we can't rewrite the top level, wrap the expr in an Exprs object - smallestKnown := sqlparser.Exprs{sqlparser.CloneExpr(in)} + smallestKnown := sqlparser.Exprs{sqlparser.Clone(in)} alwaysVisit := func(node, parent sqlparser.SQLNode) bool { return true } up := func(cursor *sqlparser.Cursor) bool { - node := sqlparser.CloneSQLNode(cursor.Node()) + node := sqlparser.Clone(cursor.Node()) s := &shrinker{orig: node} expr := s.Next() for expr != nil { @@ -57,7 +57,7 @@ func SimplifyExpr(in sqlparser.Expr, test CheckF) sqlparser.Expr { // loop until rewriting introduces no more changes for { - prevSmallest := sqlparser.CloneExprs(smallestKnown) + prevSmallest := sqlparser.Clone(smallestKnown) sqlparser.SafeRewrite(smallestKnown, alwaysVisit, up) if sqlparser.Equals.Exprs(prevSmallest, smallestKnown) { break @@ -185,7 +185,7 @@ func (s *shrinker) fillQueue() bool { s.queue = append(s.queue, ae) } - clone := sqlparser.CloneAggrFunc(e) + clone := sqlparser.Clone(e) if da, ok := clone.(sqlparser.DistinctableAggr); ok { if da.IsDistinct() { da.SetDistinct(false) diff --git a/go/vt/vtgate/simplifier/simplifier.go b/go/vt/vtgate/simplifier/simplifier.go index e96660c99ec..e838450e3a2 100644 --- a/go/vt/vtgate/simplifier/simplifier.go +++ b/go/vt/vtgate/simplifier/simplifier.go @@ -37,31 +37,31 @@ func SimplifyStatement( test := func(s sqlparser.SelectStatement) bool { // Since our semantic analysis changes the AST, we clone it first, so we have a pristine AST to play with - return testF(sqlparser.CloneSelectStatement(s)) + return testF(sqlparser.Clone(s)) } // first we try to simplify the query by removing any unions - if success := trySimplifyUnions(sqlparser.CloneSelectStatement(in), test); success != nil { + if success := trySimplifyUnions(sqlparser.Clone(in), test); success != nil { return SimplifyStatement(success, currentDB, si, testF) } // then we try to remove a table and all uses of it - if success := tryRemoveTable(tables, sqlparser.CloneSelectStatement(in), currentDB, si, testF); success != nil { + if success := tryRemoveTable(tables, sqlparser.Clone(in), currentDB, si, testF); success != nil { return SimplifyStatement(success, currentDB, si, testF) } // now let's try to simplify * expressions - if success := simplifyStarExpr(sqlparser.CloneSelectStatement(in), test); success != nil { + if success := simplifyStarExpr(sqlparser.Clone(in), test); success != nil { return SimplifyStatement(success, currentDB, si, testF) } // we try to remove/replace any expressions next - if success := trySimplifyExpressions(sqlparser.CloneSelectStatement(in), test); success != nil { + if success := trySimplifyExpressions(sqlparser.Clone(in), test); success != nil { return SimplifyStatement(success, currentDB, si, testF) } // we try to remove distinct last - if success := trySimplifyDistinct(sqlparser.CloneSelectStatement(in), test); success != nil { + if success := trySimplifyDistinct(sqlparser.Clone(in), test); success != nil { return SimplifyStatement(success, currentDB, si, testF) } @@ -144,10 +144,10 @@ func trySimplifyExpressions(in sqlparser.SelectStatement, test func(sqlparser.Se func trySimplifyUnions(in sqlparser.SelectStatement, test func(sqlparser.SelectStatement) bool) (res sqlparser.SelectStatement) { if union, ok := in.(*sqlparser.Union); ok { // the root object is an UNION - if test(sqlparser.CloneSelectStatement(union.Left)) { + if test(sqlparser.Clone(union.Left)) { return union.Left } - if test(sqlparser.CloneSelectStatement(union.Right)) { + if test(sqlparser.Clone(union.Right)) { return union.Right } } @@ -165,14 +165,14 @@ func trySimplifyUnions(in sqlparser.SelectStatement, test func(sqlparser.SelectS return true } cursor.Replace(node.Left) - clone := sqlparser.CloneSelectStatement(in) + clone := sqlparser.Clone(in) if test(clone) { log.Errorf("replaced UNION with its left child: %s -> %s", sqlparser.String(node), sqlparser.String(node.Left)) simplified = true return true } cursor.Replace(node.Right) - clone = sqlparser.CloneSelectStatement(in) + clone = sqlparser.Clone(in) if test(clone) { log.Errorf("replaced UNION with its right child: %s -> %s", sqlparser.String(node), sqlparser.String(node.Right)) simplified = true @@ -196,7 +196,7 @@ func trySimplifyUnions(in sqlparser.SelectStatement, test func(sqlparser.SelectS func tryRemoveTable(tables []semantics.TableInfo, in sqlparser.SelectStatement, currentDB string, si semantics.SchemaInformation, test func(sqlparser.SelectStatement) bool) sqlparser.SelectStatement { // we start by removing one table at a time, and see if we still have an interesting plan for idx, tbl := range tables { - clone := sqlparser.CloneSelectStatement(in) + clone := sqlparser.Clone(in) searchedTS := semantics.SingleTableSet(idx) simplified := removeTable(clone, searchedTS, currentDB, si) name, _ := tbl.Name() @@ -211,7 +211,7 @@ func tryRemoveTable(tables []semantics.TableInfo, in sqlparser.SelectStatement, func getTables(in sqlparser.SelectStatement, currentDB string, si semantics.SchemaInformation) ([]semantics.TableInfo, error) { // Since our semantic analysis changes the AST, we clone it first, so we have a pristine AST to play with - clone := sqlparser.CloneSelectStatement(in) + clone := sqlparser.Clone(in) semTable, err := semantics.Analyze(clone, currentDB, si) if err != nil { return nil, err @@ -467,7 +467,7 @@ func visitSelectExprs(node sqlparser.SelectExprs, cursor *sqlparser.Cursor, visi continue } removed := false - original := sqlparser.CloneExpr(expr.Expr) + original := sqlparser.Clone(expr.Expr) item := newExprCursor( expr.Expr, /*replace*/ func(replaceWith sqlparser.Expr) { @@ -561,7 +561,7 @@ func visitOrderBy(node sqlparser.OrderBy, cursor *sqlparser.Cursor, visit func(e for idx := 0; idx < len(node); idx++ { order := node[idx] removed := false - original := sqlparser.CloneExpr(order.Expr) + original := sqlparser.Clone(order.Expr) item := newExprCursor( order.Expr, /*replace*/ func(replaceWith sqlparser.Expr) { diff --git a/go/vt/vtgate/vindexes/vschema.go b/go/vt/vtgate/vindexes/vschema.go index 020b07f7073..924a28b309d 100644 --- a/go/vt/vtgate/vindexes/vschema.go +++ b/go/vt/vtgate/vindexes/vschema.go @@ -1242,7 +1242,7 @@ func (vschema *VSchema) FindView(keyspace, name string) sqlparser.SelectStatemen } // We do this to make sure there is no shared state between uses of this AST - statement = sqlparser.CloneSelectStatement(statement) + statement = sqlparser.Clone(statement) sqlparser.SafeRewrite(statement, nil, func(cursor *sqlparser.Cursor) bool { col, ok := cursor.Node().(*sqlparser.ColName) if ok { diff --git a/go/vt/vtgate/vschema_manager.go b/go/vt/vtgate/vschema_manager.go index dbac5589ce8..c73266af769 100644 --- a/go/vt/vtgate/vschema_manager.go +++ b/go/vt/vtgate/vschema_manager.go @@ -213,7 +213,7 @@ func (vm *VSchemaManager) updateViewInfo(ks *vindexes.KeyspaceSchema, ksName str if views != nil { ks.Views = make(map[string]sqlparser.SelectStatement, len(views)) for name, def := range views { - ks.Views[name] = sqlparser.CloneSelectStatement(def) + ks.Views[name] = sqlparser.Clone(def) } } } diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index ebce8f0619c..2fff13d3f73 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -1402,7 +1402,7 @@ func (e *Executor) duplicateCreateTable(ctx context.Context, onlineDDL *schema.O if !ok { return nil, nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "expected CreateTable statement, got: %v", sqlparser.CanonicalString(stmt)) } - newCreateTable = sqlparser.CloneRefOfCreateTable(originalCreateTable) + newCreateTable = sqlparser.Clone(originalCreateTable) newCreateTable.SetTable(newCreateTable.GetTable().Qualifier.CompliantName(), newTableName) // manipulate CreateTable statement: take care of constraints names which have to be // unique across the schema @@ -3033,7 +3033,7 @@ func (e *Executor) executeCreateDDLActionMigration(ctx context.Context, onlineDD } } if originalCreateTable, ok := ddlStmt.(*sqlparser.CreateTable); ok { - newCreateTable := sqlparser.CloneRefOfCreateTable(originalCreateTable) + newCreateTable := sqlparser.Clone(originalCreateTable) // Rewrite this CREATE TABLE statement such that CONSTRAINT names are edited, // specifically removing any prefix. if _, err := e.validateAndEditCreateTableStatement(onlineDDL, newCreateTable); err != nil { @@ -3117,7 +3117,7 @@ func (e *Executor) executeAlterViewOnline(ctx context.Context, onlineDDL *schema Select: viewStmt.Select, CheckOption: viewStmt.CheckOption, IsReplace: true, - Comments: sqlparser.CloneRefOfParsedComments(viewStmt.Comments), + Comments: sqlparser.Clone(viewStmt.Comments), } stmt.SetTable("", artifactViewName) default: From b49494e5b4c821ef79e08e86bb18e9c3e6bbdb43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicent=20Mart=C3=AD?= <42793+vmg@users.noreply.github.com> Date: Mon, 10 Jun 2024 11:08:12 +0200 Subject: [PATCH 12/40] Linkname removal (step 1) (#16016) Signed-off-by: Vicent Marti --- go/cache/theine/store.go | 6 +- go/hack/compat.go | 28 - go/hack/hack.go | 2 +- go/hack/msize.go | 76 +++ go/hack/runtime.go | 48 -- go/mysql/fastparse/atof.go | 302 ++++++++++ go/mysql/fastparse/eisel_lemire.go | 837 +++++++++++++++++++++++++++ go/mysql/fastparse/fastparse.go | 7 +- go/mysql/fastparse/fastparse_test.go | 2 +- go/vt/vtgate/evalengine/weights.go | 8 +- 10 files changed, 1227 insertions(+), 89 deletions(-) create mode 100644 go/hack/msize.go delete mode 100644 go/hack/runtime.go create mode 100644 go/mysql/fastparse/atof.go create mode 100644 go/mysql/fastparse/eisel_lemire.go diff --git a/go/cache/theine/store.go b/go/cache/theine/store.go index cef5a89c8b7..0e444c2206a 100644 --- a/go/cache/theine/store.go +++ b/go/cache/theine/store.go @@ -18,6 +18,7 @@ limitations under the License. package theine import ( + "hash/maphash" "runtime" "sync" "sync/atomic" @@ -26,7 +27,6 @@ import ( "github.com/gammazero/deque" "vitess.io/vitess/go/cache/theine/bf" - "vitess.io/vitess/go/hack" ) const ( @@ -138,10 +138,12 @@ func (h HashKey256) Hash2() (uint64, uint64) { return h0, h1 } +var cacheStringHashSeed = maphash.MakeSeed() + type StringKey string func (h StringKey) Hash() uint64 { - return hack.RuntimeStrhash(string(h), 13850135847636357301) + return maphash.String(cacheStringHashSeed, string(h)) } func (h StringKey) Hash2() (uint64, uint64) { diff --git a/go/hack/compat.go b/go/hack/compat.go index 06fa0d7228f..056ea666508 100644 --- a/go/hack/compat.go +++ b/go/hack/compat.go @@ -27,31 +27,3 @@ func String(b []byte) (s string) { func StringBytes(s string) []byte { return []byte(s) } - -// RuntimeMemhash is a slow hash function for bytes, implemented for compatibility. -func RuntimeMemhash(b []byte, hash uint64) uint64 { - for i := 0; i < len(b); i++ { - hash *= 1099511628211 - hash ^= uint64(b[i]) - } - return hash -} - -// RuntimeStrhash is a slow hash function for bytes, implemented for compatibility. -func RuntimeStrhash(str string, hash uint64) uint64 { - for i := 0; i < len(str); i++ { - hash *= 1099511628211 - hash ^= uint64(str[i]) - } - return hash -} - -// ParseFloatPrefix exposes the internal strconv method from the standard library -// -//go:linkname ParseFloatPrefix strconv.parseFloatPrefix -func ParseFloatPrefix(s string, bitSize int) (float64, int, error) - -// RuntimeAllocSize is a no-op when Vitess is not compiled with GC -func RuntimeAllocSize(size int64) int64 { - return size -} diff --git a/go/hack/hack.go b/go/hack/hack.go index 95bf11f5530..4ffbe4c3117 100644 --- a/go/hack/hack.go +++ b/go/hack/hack.go @@ -30,7 +30,7 @@ func String(b []byte) (s string) { if len(b) == 0 { return "" } - return *(*string)(unsafe.Pointer(&b)) + return unsafe.String(&b[0], len(b)) } // StringBytes returns the underlying bytes for a string. Modifying this byte slice diff --git a/go/hack/msize.go b/go/hack/msize.go new file mode 100644 index 00000000000..aead790e627 --- /dev/null +++ b/go/hack/msize.go @@ -0,0 +1,76 @@ +/* +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// Copied from the Go runtime, msize_noallocheaders.go + +package hack + +const ( + _MaxSmallSize = 32768 + smallSizeDiv = 8 + smallSizeMax = 1024 + largeSizeDiv = 128 + _NumSizeClasses = 68 + _PageShift = 13 + _PageSize = 1 << _PageShift +) + +var class_to_size = [_NumSizeClasses]uint16{0, 8, 16, 24, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896, 1024, 1152, 1280, 1408, 1536, 1792, 2048, 2304, 2688, 3072, 3200, 3456, 4096, 4864, 5376, 6144, 6528, 6784, 6912, 8192, 9472, 9728, 10240, 10880, 12288, 13568, 14336, 16384, 18432, 19072, 20480, 21760, 24576, 27264, 28672, 32768} +var size_to_class8 = [smallSizeMax/smallSizeDiv + 1]uint8{0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32} +var size_to_class128 = [(_MaxSmallSize-smallSizeMax)/largeSizeDiv + 1]uint8{32, 33, 34, 35, 36, 37, 37, 38, 38, 39, 39, 40, 40, 40, 41, 41, 41, 42, 43, 43, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 49, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67} + +func alignUp(n, a uintptr) uintptr { + return (n + a - 1) &^ (a - 1) +} + +func divRoundUp(n, a uintptr) uintptr { + // a is generally a power of two. This will get inlined and + // the compiler will optimize the division. + return (n + a - 1) / a +} + +func roundupsize(size uintptr) uintptr { + if size < _MaxSmallSize { + if size <= smallSizeMax-8 { + return uintptr(class_to_size[size_to_class8[divRoundUp(size, smallSizeDiv)]]) + } else { + return uintptr(class_to_size[size_to_class128[divRoundUp(size-smallSizeMax, largeSizeDiv)]]) + } + } + if size+_PageSize < size { + return size + } + return alignUp(size, _PageSize) +} + +// RuntimeAllocSize returns size of the memory block that mallocgc will allocate if you ask for the size. +func RuntimeAllocSize(size int64) int64 { + return int64(roundupsize(uintptr(size))) +} diff --git a/go/hack/runtime.go b/go/hack/runtime.go deleted file mode 100644 index 74bce583a84..00000000000 --- a/go/hack/runtime.go +++ /dev/null @@ -1,48 +0,0 @@ -//go:build gc && !wasm - -/* -Copyright 2021 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package hack - -import ( - "unsafe" -) - -//go:noescape -//go:linkname strhash runtime.strhash -func strhash(p unsafe.Pointer, h uintptr) uintptr - -// RuntimeStrhash provides access to the Go runtime's default hash function for strings. -// This is an optimal hash function which takes an input seed and is potentially implemented in hardware -// for most architectures. This is the same hash function that the language's `map` uses. -func RuntimeStrhash(str string, seed uint64) uint64 { - return uint64(strhash(unsafe.Pointer(&str), uintptr(seed))) -} - -//go:linkname roundupsize runtime.roundupsize -func roundupsize(size uintptr) uintptr - -// RuntimeAllocSize returns size of the memory block that mallocgc will allocate if you ask for the size. -func RuntimeAllocSize(size int64) int64 { - return int64(roundupsize(uintptr(size))) -} - -//go:linkname Atof64 strconv.atof64 -func Atof64(s string) (float64, int, error) - -//go:linkname Atof32 strconv.atof32 -func Atof32(s string) (float32, int, error) diff --git a/go/mysql/fastparse/atof.go b/go/mysql/fastparse/atof.go new file mode 100644 index 00000000000..4193031c987 --- /dev/null +++ b/go/mysql/fastparse/atof.go @@ -0,0 +1,302 @@ +/* +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// Copied from the Go runtime, package strconv + +package fastparse + +// decimal to binary floating point conversion. +// Algorithm: +// 1) Store input in multiprecision decimal. +// 2) Multiply/divide decimal by powers of two until in range [0.5, 1) +// 3) Multiply by 2^precision and round to get mantissa. + +import ( + "math" + "strconv" +) + +type floatInfo struct { + mantbits uint + expbits uint + bias int +} + +func lower(c byte) byte { + return c | ('x' - 'X') +} + +var float32info = floatInfo{23, 8, -127} +var float64info = floatInfo{52, 11, -1023} + +// commonPrefixLenIgnoreCase returns the length of the common +// prefix of s and prefix, with the character case of s ignored. +// The prefix argument must be all lower-case. +func commonPrefixLenIgnoreCase(s, prefix string) int { + n := len(prefix) + if n > len(s) { + n = len(s) + } + for i := 0; i < n; i++ { + c := s[i] + if 'A' <= c && c <= 'Z' { + c += 'a' - 'A' + } + if c != prefix[i] { + return i + } + } + return n +} + +// special returns the floating-point value for the special, +// possibly signed floating-point representations inf, infinity, +// and NaN. The result is ok if a prefix of s contains one +// of these representations and n is the length of that prefix. +// The character case is ignored. +func special(s string) (f float64, n int, ok bool) { + if len(s) == 0 { + return 0, 0, false + } + sign := 1 + nsign := 0 + switch s[0] { + case '+', '-': + if s[0] == '-' { + sign = -1 + } + nsign = 1 + s = s[1:] + fallthrough + case 'i', 'I': + n := commonPrefixLenIgnoreCase(s, "infinity") + // Anything longer than "inf" is ok, but if we + // don't have "infinity", only consume "inf". + if 3 < n && n < 8 { + n = 3 + } + if n == 3 || n == 8 { + return math.Inf(sign), nsign + n, true + } + case 'n', 'N': + if commonPrefixLenIgnoreCase(s, "nan") == 3 { + return math.NaN(), 3, true + } + } + return 0, 0, false +} + +// readFloat reads a decimal or hexadecimal mantissa and exponent from a float +// string representation in s; the number may be followed by other characters. +// readFloat reports the number of bytes consumed (i), and whether the number +// is valid (ok). +func readFloat(s string) (mantissa uint64, exp int, neg, trunc bool, i int, ok bool) { + const base = 10 + + // optional sign + if i >= len(s) { + return + } + switch { + case s[i] == '+': + i++ + case s[i] == '-': + neg = true + i++ + } + + // digits + maxMantDigits := 19 // 10^19 fits in uint64 + expChar := byte('e') + sawdot := false + sawdigits := false + nd := 0 + ndMant := 0 + dp := 0 +loop: + for ; i < len(s); i++ { + switch c := s[i]; true { + case c == '.': + if sawdot { + break loop + } + sawdot = true + dp = nd + continue + + case '0' <= c && c <= '9': + sawdigits = true + if c == '0' && nd == 0 { // ignore leading zeros + dp-- + continue + } + nd++ + if ndMant < maxMantDigits { + mantissa *= base + mantissa += uint64(c - '0') + ndMant++ + } else if c != '0' { + trunc = true + } + continue + } + break + } + if !sawdigits { + return + } + if !sawdot { + dp = nd + } + + // optional exponent moves decimal point. + // if we read a very large, very long number, + // just be sure to move the decimal point by + // a lot (say, 100000). it doesn't matter if it's + // not the exact number. + if i < len(s) && lower(s[i]) == expChar { + i++ + if i >= len(s) { + return + } + esign := 1 + if s[i] == '+' { + i++ + } else if s[i] == '-' { + i++ + esign = -1 + } + if i >= len(s) || s[i] < '0' || s[i] > '9' { + return + } + e := 0 + for ; i < len(s) && ('0' <= s[i] && s[i] <= '9'); i++ { + if e < 10000 { + e = e*10 + int(s[i]) - '0' + } + } + dp += e * esign + } + + if mantissa != 0 { + exp = dp - ndMant + } + + ok = true + return +} + +// Exact powers of 10. +var float64pow10 = []float64{ + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22, +} +var float32pow10 = []float32{1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10} + +// If possible to convert decimal representation to 64-bit float f exactly, +// entirely in floating-point math, do so, avoiding the expense of decimalToFloatBits. +// Three common cases: +// +// value is exact integer +// value is exact integer * exact power of ten +// value is exact integer / exact power of ten +// +// These all produce potentially inexact but correctly rounded answers. +func atof64exact(mantissa uint64, exp int, neg bool) (f float64, ok bool) { + if mantissa>>float64info.mantbits != 0 { + return + } + f = float64(mantissa) + if neg { + f = -f + } + switch { + case exp == 0: + // an integer. + return f, true + // Exact integers are <= 10^15. + // Exact powers of ten are <= 10^22. + case exp > 0 && exp <= 15+22: // int * 10^k + // If exponent is big but number of digits is not, + // can move a few zeros into the integer part. + if exp > 22 { + f *= float64pow10[exp-22] + exp = 22 + } + if f > 1e15 || f < -1e15 { + // the exponent was really too large. + return + } + return f * float64pow10[exp], true + case exp < 0 && exp >= -22: // int / 10^k + return f / float64pow10[-exp], true + } + return +} + +func Atof64(s string) (f float64, n int, err error) { + if val, n, ok := special(s); ok { + return val, n, nil + } + + mantissa, exp, neg, trunc, n, ok := readFloat(s) + if !ok { + return 0, n, strconv.ErrSyntax + } + + if !trunc { + if f, ok := atof64exact(mantissa, exp, neg); ok { + return f, n, nil + } + } + f, ok = eiselLemire64(mantissa, exp, neg) + if ok { + if !trunc { + return f, n, nil + } + // Even if the mantissa was truncated, we may + // have found the correct result. Confirm by + // converting the upper mantissa bound. + fUp, ok := eiselLemire64(mantissa+1, exp, neg) + if ok && f == fUp { + return f, n, nil + } + } + + // Eisel-Lemire is incapable of parsing this float accurately; we need to + // fall back to the slow path. Fortunately, we now know how many actual + // characters the float has (it's the value of `n`), so we can simply fall + // back to the standard library, which will do the slow parsing and will + // not return an error for trailing characters after the float, because + // we have truncated it. + f, err = strconv.ParseFloat(s[:n], 64) + return f, n, err +} diff --git a/go/mysql/fastparse/eisel_lemire.go b/go/mysql/fastparse/eisel_lemire.go new file mode 100644 index 00000000000..c1426c71c15 --- /dev/null +++ b/go/mysql/fastparse/eisel_lemire.go @@ -0,0 +1,837 @@ +/* +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// Copied from the Go runtime, package strconv + +package fastparse + +// This file implements the Eisel-Lemire ParseFloat algorithm, published in +// 2020 and discussed extensively at +// https://nigeltao.github.io/blog/2020/eisel-lemire.html +// +// The original C++ implementation is at +// https://github.com/lemire/fast_double_parser/blob/644bef4306059d3be01a04e77d3cc84b379c596f/include/fast_double_parser.h#L840 +// +// This Go re-implementation closely follows the C re-implementation at +// https://github.com/google/wuffs/blob/ba3818cb6b473a2ed0b38ecfc07dbbd3a97e8ae7/internal/cgen/base/floatconv-submodule-code.c#L990 +// +// Additional testing (on over several million test strings) is done by +// https://github.com/nigeltao/parse-number-fxx-test-data/blob/5280dcfccf6d0b02a65ae282dad0b6d9de50e039/script/test-go-strconv.go + +import ( + "math" + "math/bits" +) + +func eiselLemire64(man uint64, exp10 int, neg bool) (f float64, ok bool) { + // The terse comments in this function body refer to sections of the + // https://nigeltao.github.io/blog/2020/eisel-lemire.html blog post. + + // Exp10 Range. + if man == 0 { + if neg { + f = math.Float64frombits(0x8000000000000000) // Negative zero. + } + return f, true + } + if exp10 < detailedPowersOfTenMinExp10 || detailedPowersOfTenMaxExp10 < exp10 { + return 0, false + } + + // Normalization. + clz := bits.LeadingZeros64(man) + man <<= uint(clz) + const float64ExponentBias = 1023 + retExp2 := uint64(217706*exp10>>16+64+float64ExponentBias) - uint64(clz) + + // Multiplication. + xHi, xLo := bits.Mul64(man, detailedPowersOfTen[exp10-detailedPowersOfTenMinExp10][1]) + + // Wider Approximation. + if xHi&0x1FF == 0x1FF && xLo+man < man { + yHi, yLo := bits.Mul64(man, detailedPowersOfTen[exp10-detailedPowersOfTenMinExp10][0]) + mergedHi, mergedLo := xHi, xLo+yHi + if mergedLo < xLo { + mergedHi++ + } + if mergedHi&0x1FF == 0x1FF && mergedLo+1 == 0 && yLo+man < man { + return 0, false + } + xHi, xLo = mergedHi, mergedLo + } + + // Shifting to 54 Bits. + msb := xHi >> 63 + retMantissa := xHi >> (msb + 9) + retExp2 -= 1 ^ msb + + // Half-way Ambiguity. + if xLo == 0 && xHi&0x1FF == 0 && retMantissa&3 == 1 { + return 0, false + } + + // From 54 to 53 Bits. + retMantissa += retMantissa & 1 + retMantissa >>= 1 + if retMantissa>>53 > 0 { + retMantissa >>= 1 + retExp2 += 1 + } + // retExp2 is a uint64. Zero or underflow means that we're in subnormal + // float64 space. 0x7FF or above means that we're in Inf/NaN float64 space. + // + // The if block is equivalent to (but has fewer branches than): + // if retExp2 <= 0 || retExp2 >= 0x7FF { etc } + if retExp2-1 >= 0x7FF-1 { + return 0, false + } + retBits := retExp2<<52 | retMantissa&0x000FFFFFFFFFFFFF + if neg { + retBits |= 0x8000000000000000 + } + return math.Float64frombits(retBits), true +} + +// detailedPowersOfTen{Min,Max}Exp10 is the power of 10 represented by the +// first and last rows of detailedPowersOfTen. Both bounds are inclusive. +const ( + detailedPowersOfTenMinExp10 = -348 + detailedPowersOfTenMaxExp10 = +347 +) + +// detailedPowersOfTen contains 128-bit mantissa approximations (rounded down) +// to the powers of 10. For example: +// +// - 1e43 ≈ (0xE596B7B0_C643C719 * (2 ** 79)) +// - 1e43 = (0xE596B7B0_C643C719_6D9CCD05_D0000000 * (2 ** 15)) +// +// The mantissas are explicitly listed. The exponents are implied by a linear +// expression with slope 217706.0/65536.0 ≈ log(10)/log(2). +// +// The table was generated by +// https://github.com/google/wuffs/blob/ba3818cb6b473a2ed0b38ecfc07dbbd3a97e8ae7/script/print-mpb-powers-of-10.go +var detailedPowersOfTen = [...][2]uint64{ + {0x1732C869CD60E453, 0xFA8FD5A0081C0288}, // 1e-348 + {0x0E7FBD42205C8EB4, 0x9C99E58405118195}, // 1e-347 + {0x521FAC92A873B261, 0xC3C05EE50655E1FA}, // 1e-346 + {0xE6A797B752909EF9, 0xF4B0769E47EB5A78}, // 1e-345 + {0x9028BED2939A635C, 0x98EE4A22ECF3188B}, // 1e-344 + {0x7432EE873880FC33, 0xBF29DCABA82FDEAE}, // 1e-343 + {0x113FAA2906A13B3F, 0xEEF453D6923BD65A}, // 1e-342 + {0x4AC7CA59A424C507, 0x9558B4661B6565F8}, // 1e-341 + {0x5D79BCF00D2DF649, 0xBAAEE17FA23EBF76}, // 1e-340 + {0xF4D82C2C107973DC, 0xE95A99DF8ACE6F53}, // 1e-339 + {0x79071B9B8A4BE869, 0x91D8A02BB6C10594}, // 1e-338 + {0x9748E2826CDEE284, 0xB64EC836A47146F9}, // 1e-337 + {0xFD1B1B2308169B25, 0xE3E27A444D8D98B7}, // 1e-336 + {0xFE30F0F5E50E20F7, 0x8E6D8C6AB0787F72}, // 1e-335 + {0xBDBD2D335E51A935, 0xB208EF855C969F4F}, // 1e-334 + {0xAD2C788035E61382, 0xDE8B2B66B3BC4723}, // 1e-333 + {0x4C3BCB5021AFCC31, 0x8B16FB203055AC76}, // 1e-332 + {0xDF4ABE242A1BBF3D, 0xADDCB9E83C6B1793}, // 1e-331 + {0xD71D6DAD34A2AF0D, 0xD953E8624B85DD78}, // 1e-330 + {0x8672648C40E5AD68, 0x87D4713D6F33AA6B}, // 1e-329 + {0x680EFDAF511F18C2, 0xA9C98D8CCB009506}, // 1e-328 + {0x0212BD1B2566DEF2, 0xD43BF0EFFDC0BA48}, // 1e-327 + {0x014BB630F7604B57, 0x84A57695FE98746D}, // 1e-326 + {0x419EA3BD35385E2D, 0xA5CED43B7E3E9188}, // 1e-325 + {0x52064CAC828675B9, 0xCF42894A5DCE35EA}, // 1e-324 + {0x7343EFEBD1940993, 0x818995CE7AA0E1B2}, // 1e-323 + {0x1014EBE6C5F90BF8, 0xA1EBFB4219491A1F}, // 1e-322 + {0xD41A26E077774EF6, 0xCA66FA129F9B60A6}, // 1e-321 + {0x8920B098955522B4, 0xFD00B897478238D0}, // 1e-320 + {0x55B46E5F5D5535B0, 0x9E20735E8CB16382}, // 1e-319 + {0xEB2189F734AA831D, 0xC5A890362FDDBC62}, // 1e-318 + {0xA5E9EC7501D523E4, 0xF712B443BBD52B7B}, // 1e-317 + {0x47B233C92125366E, 0x9A6BB0AA55653B2D}, // 1e-316 + {0x999EC0BB696E840A, 0xC1069CD4EABE89F8}, // 1e-315 + {0xC00670EA43CA250D, 0xF148440A256E2C76}, // 1e-314 + {0x380406926A5E5728, 0x96CD2A865764DBCA}, // 1e-313 + {0xC605083704F5ECF2, 0xBC807527ED3E12BC}, // 1e-312 + {0xF7864A44C633682E, 0xEBA09271E88D976B}, // 1e-311 + {0x7AB3EE6AFBE0211D, 0x93445B8731587EA3}, // 1e-310 + {0x5960EA05BAD82964, 0xB8157268FDAE9E4C}, // 1e-309 + {0x6FB92487298E33BD, 0xE61ACF033D1A45DF}, // 1e-308 + {0xA5D3B6D479F8E056, 0x8FD0C16206306BAB}, // 1e-307 + {0x8F48A4899877186C, 0xB3C4F1BA87BC8696}, // 1e-306 + {0x331ACDABFE94DE87, 0xE0B62E2929ABA83C}, // 1e-305 + {0x9FF0C08B7F1D0B14, 0x8C71DCD9BA0B4925}, // 1e-304 + {0x07ECF0AE5EE44DD9, 0xAF8E5410288E1B6F}, // 1e-303 + {0xC9E82CD9F69D6150, 0xDB71E91432B1A24A}, // 1e-302 + {0xBE311C083A225CD2, 0x892731AC9FAF056E}, // 1e-301 + {0x6DBD630A48AAF406, 0xAB70FE17C79AC6CA}, // 1e-300 + {0x092CBBCCDAD5B108, 0xD64D3D9DB981787D}, // 1e-299 + {0x25BBF56008C58EA5, 0x85F0468293F0EB4E}, // 1e-298 + {0xAF2AF2B80AF6F24E, 0xA76C582338ED2621}, // 1e-297 + {0x1AF5AF660DB4AEE1, 0xD1476E2C07286FAA}, // 1e-296 + {0x50D98D9FC890ED4D, 0x82CCA4DB847945CA}, // 1e-295 + {0xE50FF107BAB528A0, 0xA37FCE126597973C}, // 1e-294 + {0x1E53ED49A96272C8, 0xCC5FC196FEFD7D0C}, // 1e-293 + {0x25E8E89C13BB0F7A, 0xFF77B1FCBEBCDC4F}, // 1e-292 + {0x77B191618C54E9AC, 0x9FAACF3DF73609B1}, // 1e-291 + {0xD59DF5B9EF6A2417, 0xC795830D75038C1D}, // 1e-290 + {0x4B0573286B44AD1D, 0xF97AE3D0D2446F25}, // 1e-289 + {0x4EE367F9430AEC32, 0x9BECCE62836AC577}, // 1e-288 + {0x229C41F793CDA73F, 0xC2E801FB244576D5}, // 1e-287 + {0x6B43527578C1110F, 0xF3A20279ED56D48A}, // 1e-286 + {0x830A13896B78AAA9, 0x9845418C345644D6}, // 1e-285 + {0x23CC986BC656D553, 0xBE5691EF416BD60C}, // 1e-284 + {0x2CBFBE86B7EC8AA8, 0xEDEC366B11C6CB8F}, // 1e-283 + {0x7BF7D71432F3D6A9, 0x94B3A202EB1C3F39}, // 1e-282 + {0xDAF5CCD93FB0CC53, 0xB9E08A83A5E34F07}, // 1e-281 + {0xD1B3400F8F9CFF68, 0xE858AD248F5C22C9}, // 1e-280 + {0x23100809B9C21FA1, 0x91376C36D99995BE}, // 1e-279 + {0xABD40A0C2832A78A, 0xB58547448FFFFB2D}, // 1e-278 + {0x16C90C8F323F516C, 0xE2E69915B3FFF9F9}, // 1e-277 + {0xAE3DA7D97F6792E3, 0x8DD01FAD907FFC3B}, // 1e-276 + {0x99CD11CFDF41779C, 0xB1442798F49FFB4A}, // 1e-275 + {0x40405643D711D583, 0xDD95317F31C7FA1D}, // 1e-274 + {0x482835EA666B2572, 0x8A7D3EEF7F1CFC52}, // 1e-273 + {0xDA3243650005EECF, 0xAD1C8EAB5EE43B66}, // 1e-272 + {0x90BED43E40076A82, 0xD863B256369D4A40}, // 1e-271 + {0x5A7744A6E804A291, 0x873E4F75E2224E68}, // 1e-270 + {0x711515D0A205CB36, 0xA90DE3535AAAE202}, // 1e-269 + {0x0D5A5B44CA873E03, 0xD3515C2831559A83}, // 1e-268 + {0xE858790AFE9486C2, 0x8412D9991ED58091}, // 1e-267 + {0x626E974DBE39A872, 0xA5178FFF668AE0B6}, // 1e-266 + {0xFB0A3D212DC8128F, 0xCE5D73FF402D98E3}, // 1e-265 + {0x7CE66634BC9D0B99, 0x80FA687F881C7F8E}, // 1e-264 + {0x1C1FFFC1EBC44E80, 0xA139029F6A239F72}, // 1e-263 + {0xA327FFB266B56220, 0xC987434744AC874E}, // 1e-262 + {0x4BF1FF9F0062BAA8, 0xFBE9141915D7A922}, // 1e-261 + {0x6F773FC3603DB4A9, 0x9D71AC8FADA6C9B5}, // 1e-260 + {0xCB550FB4384D21D3, 0xC4CE17B399107C22}, // 1e-259 + {0x7E2A53A146606A48, 0xF6019DA07F549B2B}, // 1e-258 + {0x2EDA7444CBFC426D, 0x99C102844F94E0FB}, // 1e-257 + {0xFA911155FEFB5308, 0xC0314325637A1939}, // 1e-256 + {0x793555AB7EBA27CA, 0xF03D93EEBC589F88}, // 1e-255 + {0x4BC1558B2F3458DE, 0x96267C7535B763B5}, // 1e-254 + {0x9EB1AAEDFB016F16, 0xBBB01B9283253CA2}, // 1e-253 + {0x465E15A979C1CADC, 0xEA9C227723EE8BCB}, // 1e-252 + {0x0BFACD89EC191EC9, 0x92A1958A7675175F}, // 1e-251 + {0xCEF980EC671F667B, 0xB749FAED14125D36}, // 1e-250 + {0x82B7E12780E7401A, 0xE51C79A85916F484}, // 1e-249 + {0xD1B2ECB8B0908810, 0x8F31CC0937AE58D2}, // 1e-248 + {0x861FA7E6DCB4AA15, 0xB2FE3F0B8599EF07}, // 1e-247 + {0x67A791E093E1D49A, 0xDFBDCECE67006AC9}, // 1e-246 + {0xE0C8BB2C5C6D24E0, 0x8BD6A141006042BD}, // 1e-245 + {0x58FAE9F773886E18, 0xAECC49914078536D}, // 1e-244 + {0xAF39A475506A899E, 0xDA7F5BF590966848}, // 1e-243 + {0x6D8406C952429603, 0x888F99797A5E012D}, // 1e-242 + {0xC8E5087BA6D33B83, 0xAAB37FD7D8F58178}, // 1e-241 + {0xFB1E4A9A90880A64, 0xD5605FCDCF32E1D6}, // 1e-240 + {0x5CF2EEA09A55067F, 0x855C3BE0A17FCD26}, // 1e-239 + {0xF42FAA48C0EA481E, 0xA6B34AD8C9DFC06F}, // 1e-238 + {0xF13B94DAF124DA26, 0xD0601D8EFC57B08B}, // 1e-237 + {0x76C53D08D6B70858, 0x823C12795DB6CE57}, // 1e-236 + {0x54768C4B0C64CA6E, 0xA2CB1717B52481ED}, // 1e-235 + {0xA9942F5DCF7DFD09, 0xCB7DDCDDA26DA268}, // 1e-234 + {0xD3F93B35435D7C4C, 0xFE5D54150B090B02}, // 1e-233 + {0xC47BC5014A1A6DAF, 0x9EFA548D26E5A6E1}, // 1e-232 + {0x359AB6419CA1091B, 0xC6B8E9B0709F109A}, // 1e-231 + {0xC30163D203C94B62, 0xF867241C8CC6D4C0}, // 1e-230 + {0x79E0DE63425DCF1D, 0x9B407691D7FC44F8}, // 1e-229 + {0x985915FC12F542E4, 0xC21094364DFB5636}, // 1e-228 + {0x3E6F5B7B17B2939D, 0xF294B943E17A2BC4}, // 1e-227 + {0xA705992CEECF9C42, 0x979CF3CA6CEC5B5A}, // 1e-226 + {0x50C6FF782A838353, 0xBD8430BD08277231}, // 1e-225 + {0xA4F8BF5635246428, 0xECE53CEC4A314EBD}, // 1e-224 + {0x871B7795E136BE99, 0x940F4613AE5ED136}, // 1e-223 + {0x28E2557B59846E3F, 0xB913179899F68584}, // 1e-222 + {0x331AEADA2FE589CF, 0xE757DD7EC07426E5}, // 1e-221 + {0x3FF0D2C85DEF7621, 0x9096EA6F3848984F}, // 1e-220 + {0x0FED077A756B53A9, 0xB4BCA50B065ABE63}, // 1e-219 + {0xD3E8495912C62894, 0xE1EBCE4DC7F16DFB}, // 1e-218 + {0x64712DD7ABBBD95C, 0x8D3360F09CF6E4BD}, // 1e-217 + {0xBD8D794D96AACFB3, 0xB080392CC4349DEC}, // 1e-216 + {0xECF0D7A0FC5583A0, 0xDCA04777F541C567}, // 1e-215 + {0xF41686C49DB57244, 0x89E42CAAF9491B60}, // 1e-214 + {0x311C2875C522CED5, 0xAC5D37D5B79B6239}, // 1e-213 + {0x7D633293366B828B, 0xD77485CB25823AC7}, // 1e-212 + {0xAE5DFF9C02033197, 0x86A8D39EF77164BC}, // 1e-211 + {0xD9F57F830283FDFC, 0xA8530886B54DBDEB}, // 1e-210 + {0xD072DF63C324FD7B, 0xD267CAA862A12D66}, // 1e-209 + {0x4247CB9E59F71E6D, 0x8380DEA93DA4BC60}, // 1e-208 + {0x52D9BE85F074E608, 0xA46116538D0DEB78}, // 1e-207 + {0x67902E276C921F8B, 0xCD795BE870516656}, // 1e-206 + {0x00BA1CD8A3DB53B6, 0x806BD9714632DFF6}, // 1e-205 + {0x80E8A40ECCD228A4, 0xA086CFCD97BF97F3}, // 1e-204 + {0x6122CD128006B2CD, 0xC8A883C0FDAF7DF0}, // 1e-203 + {0x796B805720085F81, 0xFAD2A4B13D1B5D6C}, // 1e-202 + {0xCBE3303674053BB0, 0x9CC3A6EEC6311A63}, // 1e-201 + {0xBEDBFC4411068A9C, 0xC3F490AA77BD60FC}, // 1e-200 + {0xEE92FB5515482D44, 0xF4F1B4D515ACB93B}, // 1e-199 + {0x751BDD152D4D1C4A, 0x991711052D8BF3C5}, // 1e-198 + {0xD262D45A78A0635D, 0xBF5CD54678EEF0B6}, // 1e-197 + {0x86FB897116C87C34, 0xEF340A98172AACE4}, // 1e-196 + {0xD45D35E6AE3D4DA0, 0x9580869F0E7AAC0E}, // 1e-195 + {0x8974836059CCA109, 0xBAE0A846D2195712}, // 1e-194 + {0x2BD1A438703FC94B, 0xE998D258869FACD7}, // 1e-193 + {0x7B6306A34627DDCF, 0x91FF83775423CC06}, // 1e-192 + {0x1A3BC84C17B1D542, 0xB67F6455292CBF08}, // 1e-191 + {0x20CABA5F1D9E4A93, 0xE41F3D6A7377EECA}, // 1e-190 + {0x547EB47B7282EE9C, 0x8E938662882AF53E}, // 1e-189 + {0xE99E619A4F23AA43, 0xB23867FB2A35B28D}, // 1e-188 + {0x6405FA00E2EC94D4, 0xDEC681F9F4C31F31}, // 1e-187 + {0xDE83BC408DD3DD04, 0x8B3C113C38F9F37E}, // 1e-186 + {0x9624AB50B148D445, 0xAE0B158B4738705E}, // 1e-185 + {0x3BADD624DD9B0957, 0xD98DDAEE19068C76}, // 1e-184 + {0xE54CA5D70A80E5D6, 0x87F8A8D4CFA417C9}, // 1e-183 + {0x5E9FCF4CCD211F4C, 0xA9F6D30A038D1DBC}, // 1e-182 + {0x7647C3200069671F, 0xD47487CC8470652B}, // 1e-181 + {0x29ECD9F40041E073, 0x84C8D4DFD2C63F3B}, // 1e-180 + {0xF468107100525890, 0xA5FB0A17C777CF09}, // 1e-179 + {0x7182148D4066EEB4, 0xCF79CC9DB955C2CC}, // 1e-178 + {0xC6F14CD848405530, 0x81AC1FE293D599BF}, // 1e-177 + {0xB8ADA00E5A506A7C, 0xA21727DB38CB002F}, // 1e-176 + {0xA6D90811F0E4851C, 0xCA9CF1D206FDC03B}, // 1e-175 + {0x908F4A166D1DA663, 0xFD442E4688BD304A}, // 1e-174 + {0x9A598E4E043287FE, 0x9E4A9CEC15763E2E}, // 1e-173 + {0x40EFF1E1853F29FD, 0xC5DD44271AD3CDBA}, // 1e-172 + {0xD12BEE59E68EF47C, 0xF7549530E188C128}, // 1e-171 + {0x82BB74F8301958CE, 0x9A94DD3E8CF578B9}, // 1e-170 + {0xE36A52363C1FAF01, 0xC13A148E3032D6E7}, // 1e-169 + {0xDC44E6C3CB279AC1, 0xF18899B1BC3F8CA1}, // 1e-168 + {0x29AB103A5EF8C0B9, 0x96F5600F15A7B7E5}, // 1e-167 + {0x7415D448F6B6F0E7, 0xBCB2B812DB11A5DE}, // 1e-166 + {0x111B495B3464AD21, 0xEBDF661791D60F56}, // 1e-165 + {0xCAB10DD900BEEC34, 0x936B9FCEBB25C995}, // 1e-164 + {0x3D5D514F40EEA742, 0xB84687C269EF3BFB}, // 1e-163 + {0x0CB4A5A3112A5112, 0xE65829B3046B0AFA}, // 1e-162 + {0x47F0E785EABA72AB, 0x8FF71A0FE2C2E6DC}, // 1e-161 + {0x59ED216765690F56, 0xB3F4E093DB73A093}, // 1e-160 + {0x306869C13EC3532C, 0xE0F218B8D25088B8}, // 1e-159 + {0x1E414218C73A13FB, 0x8C974F7383725573}, // 1e-158 + {0xE5D1929EF90898FA, 0xAFBD2350644EEACF}, // 1e-157 + {0xDF45F746B74ABF39, 0xDBAC6C247D62A583}, // 1e-156 + {0x6B8BBA8C328EB783, 0x894BC396CE5DA772}, // 1e-155 + {0x066EA92F3F326564, 0xAB9EB47C81F5114F}, // 1e-154 + {0xC80A537B0EFEFEBD, 0xD686619BA27255A2}, // 1e-153 + {0xBD06742CE95F5F36, 0x8613FD0145877585}, // 1e-152 + {0x2C48113823B73704, 0xA798FC4196E952E7}, // 1e-151 + {0xF75A15862CA504C5, 0xD17F3B51FCA3A7A0}, // 1e-150 + {0x9A984D73DBE722FB, 0x82EF85133DE648C4}, // 1e-149 + {0xC13E60D0D2E0EBBA, 0xA3AB66580D5FDAF5}, // 1e-148 + {0x318DF905079926A8, 0xCC963FEE10B7D1B3}, // 1e-147 + {0xFDF17746497F7052, 0xFFBBCFE994E5C61F}, // 1e-146 + {0xFEB6EA8BEDEFA633, 0x9FD561F1FD0F9BD3}, // 1e-145 + {0xFE64A52EE96B8FC0, 0xC7CABA6E7C5382C8}, // 1e-144 + {0x3DFDCE7AA3C673B0, 0xF9BD690A1B68637B}, // 1e-143 + {0x06BEA10CA65C084E, 0x9C1661A651213E2D}, // 1e-142 + {0x486E494FCFF30A62, 0xC31BFA0FE5698DB8}, // 1e-141 + {0x5A89DBA3C3EFCCFA, 0xF3E2F893DEC3F126}, // 1e-140 + {0xF89629465A75E01C, 0x986DDB5C6B3A76B7}, // 1e-139 + {0xF6BBB397F1135823, 0xBE89523386091465}, // 1e-138 + {0x746AA07DED582E2C, 0xEE2BA6C0678B597F}, // 1e-137 + {0xA8C2A44EB4571CDC, 0x94DB483840B717EF}, // 1e-136 + {0x92F34D62616CE413, 0xBA121A4650E4DDEB}, // 1e-135 + {0x77B020BAF9C81D17, 0xE896A0D7E51E1566}, // 1e-134 + {0x0ACE1474DC1D122E, 0x915E2486EF32CD60}, // 1e-133 + {0x0D819992132456BA, 0xB5B5ADA8AAFF80B8}, // 1e-132 + {0x10E1FFF697ED6C69, 0xE3231912D5BF60E6}, // 1e-131 + {0xCA8D3FFA1EF463C1, 0x8DF5EFABC5979C8F}, // 1e-130 + {0xBD308FF8A6B17CB2, 0xB1736B96B6FD83B3}, // 1e-129 + {0xAC7CB3F6D05DDBDE, 0xDDD0467C64BCE4A0}, // 1e-128 + {0x6BCDF07A423AA96B, 0x8AA22C0DBEF60EE4}, // 1e-127 + {0x86C16C98D2C953C6, 0xAD4AB7112EB3929D}, // 1e-126 + {0xE871C7BF077BA8B7, 0xD89D64D57A607744}, // 1e-125 + {0x11471CD764AD4972, 0x87625F056C7C4A8B}, // 1e-124 + {0xD598E40D3DD89BCF, 0xA93AF6C6C79B5D2D}, // 1e-123 + {0x4AFF1D108D4EC2C3, 0xD389B47879823479}, // 1e-122 + {0xCEDF722A585139BA, 0x843610CB4BF160CB}, // 1e-121 + {0xC2974EB4EE658828, 0xA54394FE1EEDB8FE}, // 1e-120 + {0x733D226229FEEA32, 0xCE947A3DA6A9273E}, // 1e-119 + {0x0806357D5A3F525F, 0x811CCC668829B887}, // 1e-118 + {0xCA07C2DCB0CF26F7, 0xA163FF802A3426A8}, // 1e-117 + {0xFC89B393DD02F0B5, 0xC9BCFF6034C13052}, // 1e-116 + {0xBBAC2078D443ACE2, 0xFC2C3F3841F17C67}, // 1e-115 + {0xD54B944B84AA4C0D, 0x9D9BA7832936EDC0}, // 1e-114 + {0x0A9E795E65D4DF11, 0xC5029163F384A931}, // 1e-113 + {0x4D4617B5FF4A16D5, 0xF64335BCF065D37D}, // 1e-112 + {0x504BCED1BF8E4E45, 0x99EA0196163FA42E}, // 1e-111 + {0xE45EC2862F71E1D6, 0xC06481FB9BCF8D39}, // 1e-110 + {0x5D767327BB4E5A4C, 0xF07DA27A82C37088}, // 1e-109 + {0x3A6A07F8D510F86F, 0x964E858C91BA2655}, // 1e-108 + {0x890489F70A55368B, 0xBBE226EFB628AFEA}, // 1e-107 + {0x2B45AC74CCEA842E, 0xEADAB0ABA3B2DBE5}, // 1e-106 + {0x3B0B8BC90012929D, 0x92C8AE6B464FC96F}, // 1e-105 + {0x09CE6EBB40173744, 0xB77ADA0617E3BBCB}, // 1e-104 + {0xCC420A6A101D0515, 0xE55990879DDCAABD}, // 1e-103 + {0x9FA946824A12232D, 0x8F57FA54C2A9EAB6}, // 1e-102 + {0x47939822DC96ABF9, 0xB32DF8E9F3546564}, // 1e-101 + {0x59787E2B93BC56F7, 0xDFF9772470297EBD}, // 1e-100 + {0x57EB4EDB3C55B65A, 0x8BFBEA76C619EF36}, // 1e-99 + {0xEDE622920B6B23F1, 0xAEFAE51477A06B03}, // 1e-98 + {0xE95FAB368E45ECED, 0xDAB99E59958885C4}, // 1e-97 + {0x11DBCB0218EBB414, 0x88B402F7FD75539B}, // 1e-96 + {0xD652BDC29F26A119, 0xAAE103B5FCD2A881}, // 1e-95 + {0x4BE76D3346F0495F, 0xD59944A37C0752A2}, // 1e-94 + {0x6F70A4400C562DDB, 0x857FCAE62D8493A5}, // 1e-93 + {0xCB4CCD500F6BB952, 0xA6DFBD9FB8E5B88E}, // 1e-92 + {0x7E2000A41346A7A7, 0xD097AD07A71F26B2}, // 1e-91 + {0x8ED400668C0C28C8, 0x825ECC24C873782F}, // 1e-90 + {0x728900802F0F32FA, 0xA2F67F2DFA90563B}, // 1e-89 + {0x4F2B40A03AD2FFB9, 0xCBB41EF979346BCA}, // 1e-88 + {0xE2F610C84987BFA8, 0xFEA126B7D78186BC}, // 1e-87 + {0x0DD9CA7D2DF4D7C9, 0x9F24B832E6B0F436}, // 1e-86 + {0x91503D1C79720DBB, 0xC6EDE63FA05D3143}, // 1e-85 + {0x75A44C6397CE912A, 0xF8A95FCF88747D94}, // 1e-84 + {0xC986AFBE3EE11ABA, 0x9B69DBE1B548CE7C}, // 1e-83 + {0xFBE85BADCE996168, 0xC24452DA229B021B}, // 1e-82 + {0xFAE27299423FB9C3, 0xF2D56790AB41C2A2}, // 1e-81 + {0xDCCD879FC967D41A, 0x97C560BA6B0919A5}, // 1e-80 + {0x5400E987BBC1C920, 0xBDB6B8E905CB600F}, // 1e-79 + {0x290123E9AAB23B68, 0xED246723473E3813}, // 1e-78 + {0xF9A0B6720AAF6521, 0x9436C0760C86E30B}, // 1e-77 + {0xF808E40E8D5B3E69, 0xB94470938FA89BCE}, // 1e-76 + {0xB60B1D1230B20E04, 0xE7958CB87392C2C2}, // 1e-75 + {0xB1C6F22B5E6F48C2, 0x90BD77F3483BB9B9}, // 1e-74 + {0x1E38AEB6360B1AF3, 0xB4ECD5F01A4AA828}, // 1e-73 + {0x25C6DA63C38DE1B0, 0xE2280B6C20DD5232}, // 1e-72 + {0x579C487E5A38AD0E, 0x8D590723948A535F}, // 1e-71 + {0x2D835A9DF0C6D851, 0xB0AF48EC79ACE837}, // 1e-70 + {0xF8E431456CF88E65, 0xDCDB1B2798182244}, // 1e-69 + {0x1B8E9ECB641B58FF, 0x8A08F0F8BF0F156B}, // 1e-68 + {0xE272467E3D222F3F, 0xAC8B2D36EED2DAC5}, // 1e-67 + {0x5B0ED81DCC6ABB0F, 0xD7ADF884AA879177}, // 1e-66 + {0x98E947129FC2B4E9, 0x86CCBB52EA94BAEA}, // 1e-65 + {0x3F2398D747B36224, 0xA87FEA27A539E9A5}, // 1e-64 + {0x8EEC7F0D19A03AAD, 0xD29FE4B18E88640E}, // 1e-63 + {0x1953CF68300424AC, 0x83A3EEEEF9153E89}, // 1e-62 + {0x5FA8C3423C052DD7, 0xA48CEAAAB75A8E2B}, // 1e-61 + {0x3792F412CB06794D, 0xCDB02555653131B6}, // 1e-60 + {0xE2BBD88BBEE40BD0, 0x808E17555F3EBF11}, // 1e-59 + {0x5B6ACEAEAE9D0EC4, 0xA0B19D2AB70E6ED6}, // 1e-58 + {0xF245825A5A445275, 0xC8DE047564D20A8B}, // 1e-57 + {0xEED6E2F0F0D56712, 0xFB158592BE068D2E}, // 1e-56 + {0x55464DD69685606B, 0x9CED737BB6C4183D}, // 1e-55 + {0xAA97E14C3C26B886, 0xC428D05AA4751E4C}, // 1e-54 + {0xD53DD99F4B3066A8, 0xF53304714D9265DF}, // 1e-53 + {0xE546A8038EFE4029, 0x993FE2C6D07B7FAB}, // 1e-52 + {0xDE98520472BDD033, 0xBF8FDB78849A5F96}, // 1e-51 + {0x963E66858F6D4440, 0xEF73D256A5C0F77C}, // 1e-50 + {0xDDE7001379A44AA8, 0x95A8637627989AAD}, // 1e-49 + {0x5560C018580D5D52, 0xBB127C53B17EC159}, // 1e-48 + {0xAAB8F01E6E10B4A6, 0xE9D71B689DDE71AF}, // 1e-47 + {0xCAB3961304CA70E8, 0x9226712162AB070D}, // 1e-46 + {0x3D607B97C5FD0D22, 0xB6B00D69BB55C8D1}, // 1e-45 + {0x8CB89A7DB77C506A, 0xE45C10C42A2B3B05}, // 1e-44 + {0x77F3608E92ADB242, 0x8EB98A7A9A5B04E3}, // 1e-43 + {0x55F038B237591ED3, 0xB267ED1940F1C61C}, // 1e-42 + {0x6B6C46DEC52F6688, 0xDF01E85F912E37A3}, // 1e-41 + {0x2323AC4B3B3DA015, 0x8B61313BBABCE2C6}, // 1e-40 + {0xABEC975E0A0D081A, 0xAE397D8AA96C1B77}, // 1e-39 + {0x96E7BD358C904A21, 0xD9C7DCED53C72255}, // 1e-38 + {0x7E50D64177DA2E54, 0x881CEA14545C7575}, // 1e-37 + {0xDDE50BD1D5D0B9E9, 0xAA242499697392D2}, // 1e-36 + {0x955E4EC64B44E864, 0xD4AD2DBFC3D07787}, // 1e-35 + {0xBD5AF13BEF0B113E, 0x84EC3C97DA624AB4}, // 1e-34 + {0xECB1AD8AEACDD58E, 0xA6274BBDD0FADD61}, // 1e-33 + {0x67DE18EDA5814AF2, 0xCFB11EAD453994BA}, // 1e-32 + {0x80EACF948770CED7, 0x81CEB32C4B43FCF4}, // 1e-31 + {0xA1258379A94D028D, 0xA2425FF75E14FC31}, // 1e-30 + {0x096EE45813A04330, 0xCAD2F7F5359A3B3E}, // 1e-29 + {0x8BCA9D6E188853FC, 0xFD87B5F28300CA0D}, // 1e-28 + {0x775EA264CF55347D, 0x9E74D1B791E07E48}, // 1e-27 + {0x95364AFE032A819D, 0xC612062576589DDA}, // 1e-26 + {0x3A83DDBD83F52204, 0xF79687AED3EEC551}, // 1e-25 + {0xC4926A9672793542, 0x9ABE14CD44753B52}, // 1e-24 + {0x75B7053C0F178293, 0xC16D9A0095928A27}, // 1e-23 + {0x5324C68B12DD6338, 0xF1C90080BAF72CB1}, // 1e-22 + {0xD3F6FC16EBCA5E03, 0x971DA05074DA7BEE}, // 1e-21 + {0x88F4BB1CA6BCF584, 0xBCE5086492111AEA}, // 1e-20 + {0x2B31E9E3D06C32E5, 0xEC1E4A7DB69561A5}, // 1e-19 + {0x3AFF322E62439FCF, 0x9392EE8E921D5D07}, // 1e-18 + {0x09BEFEB9FAD487C2, 0xB877AA3236A4B449}, // 1e-17 + {0x4C2EBE687989A9B3, 0xE69594BEC44DE15B}, // 1e-16 + {0x0F9D37014BF60A10, 0x901D7CF73AB0ACD9}, // 1e-15 + {0x538484C19EF38C94, 0xB424DC35095CD80F}, // 1e-14 + {0x2865A5F206B06FB9, 0xE12E13424BB40E13}, // 1e-13 + {0xF93F87B7442E45D3, 0x8CBCCC096F5088CB}, // 1e-12 + {0xF78F69A51539D748, 0xAFEBFF0BCB24AAFE}, // 1e-11 + {0xB573440E5A884D1B, 0xDBE6FECEBDEDD5BE}, // 1e-10 + {0x31680A88F8953030, 0x89705F4136B4A597}, // 1e-9 + {0xFDC20D2B36BA7C3D, 0xABCC77118461CEFC}, // 1e-8 + {0x3D32907604691B4C, 0xD6BF94D5E57A42BC}, // 1e-7 + {0xA63F9A49C2C1B10F, 0x8637BD05AF6C69B5}, // 1e-6 + {0x0FCF80DC33721D53, 0xA7C5AC471B478423}, // 1e-5 + {0xD3C36113404EA4A8, 0xD1B71758E219652B}, // 1e-4 + {0x645A1CAC083126E9, 0x83126E978D4FDF3B}, // 1e-3 + {0x3D70A3D70A3D70A3, 0xA3D70A3D70A3D70A}, // 1e-2 + {0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC}, // 1e-1 + {0x0000000000000000, 0x8000000000000000}, // 1e0 + {0x0000000000000000, 0xA000000000000000}, // 1e1 + {0x0000000000000000, 0xC800000000000000}, // 1e2 + {0x0000000000000000, 0xFA00000000000000}, // 1e3 + {0x0000000000000000, 0x9C40000000000000}, // 1e4 + {0x0000000000000000, 0xC350000000000000}, // 1e5 + {0x0000000000000000, 0xF424000000000000}, // 1e6 + {0x0000000000000000, 0x9896800000000000}, // 1e7 + {0x0000000000000000, 0xBEBC200000000000}, // 1e8 + {0x0000000000000000, 0xEE6B280000000000}, // 1e9 + {0x0000000000000000, 0x9502F90000000000}, // 1e10 + {0x0000000000000000, 0xBA43B74000000000}, // 1e11 + {0x0000000000000000, 0xE8D4A51000000000}, // 1e12 + {0x0000000000000000, 0x9184E72A00000000}, // 1e13 + {0x0000000000000000, 0xB5E620F480000000}, // 1e14 + {0x0000000000000000, 0xE35FA931A0000000}, // 1e15 + {0x0000000000000000, 0x8E1BC9BF04000000}, // 1e16 + {0x0000000000000000, 0xB1A2BC2EC5000000}, // 1e17 + {0x0000000000000000, 0xDE0B6B3A76400000}, // 1e18 + {0x0000000000000000, 0x8AC7230489E80000}, // 1e19 + {0x0000000000000000, 0xAD78EBC5AC620000}, // 1e20 + {0x0000000000000000, 0xD8D726B7177A8000}, // 1e21 + {0x0000000000000000, 0x878678326EAC9000}, // 1e22 + {0x0000000000000000, 0xA968163F0A57B400}, // 1e23 + {0x0000000000000000, 0xD3C21BCECCEDA100}, // 1e24 + {0x0000000000000000, 0x84595161401484A0}, // 1e25 + {0x0000000000000000, 0xA56FA5B99019A5C8}, // 1e26 + {0x0000000000000000, 0xCECB8F27F4200F3A}, // 1e27 + {0x4000000000000000, 0x813F3978F8940984}, // 1e28 + {0x5000000000000000, 0xA18F07D736B90BE5}, // 1e29 + {0xA400000000000000, 0xC9F2C9CD04674EDE}, // 1e30 + {0x4D00000000000000, 0xFC6F7C4045812296}, // 1e31 + {0xF020000000000000, 0x9DC5ADA82B70B59D}, // 1e32 + {0x6C28000000000000, 0xC5371912364CE305}, // 1e33 + {0xC732000000000000, 0xF684DF56C3E01BC6}, // 1e34 + {0x3C7F400000000000, 0x9A130B963A6C115C}, // 1e35 + {0x4B9F100000000000, 0xC097CE7BC90715B3}, // 1e36 + {0x1E86D40000000000, 0xF0BDC21ABB48DB20}, // 1e37 + {0x1314448000000000, 0x96769950B50D88F4}, // 1e38 + {0x17D955A000000000, 0xBC143FA4E250EB31}, // 1e39 + {0x5DCFAB0800000000, 0xEB194F8E1AE525FD}, // 1e40 + {0x5AA1CAE500000000, 0x92EFD1B8D0CF37BE}, // 1e41 + {0xF14A3D9E40000000, 0xB7ABC627050305AD}, // 1e42 + {0x6D9CCD05D0000000, 0xE596B7B0C643C719}, // 1e43 + {0xE4820023A2000000, 0x8F7E32CE7BEA5C6F}, // 1e44 + {0xDDA2802C8A800000, 0xB35DBF821AE4F38B}, // 1e45 + {0xD50B2037AD200000, 0xE0352F62A19E306E}, // 1e46 + {0x4526F422CC340000, 0x8C213D9DA502DE45}, // 1e47 + {0x9670B12B7F410000, 0xAF298D050E4395D6}, // 1e48 + {0x3C0CDD765F114000, 0xDAF3F04651D47B4C}, // 1e49 + {0xA5880A69FB6AC800, 0x88D8762BF324CD0F}, // 1e50 + {0x8EEA0D047A457A00, 0xAB0E93B6EFEE0053}, // 1e51 + {0x72A4904598D6D880, 0xD5D238A4ABE98068}, // 1e52 + {0x47A6DA2B7F864750, 0x85A36366EB71F041}, // 1e53 + {0x999090B65F67D924, 0xA70C3C40A64E6C51}, // 1e54 + {0xFFF4B4E3F741CF6D, 0xD0CF4B50CFE20765}, // 1e55 + {0xBFF8F10E7A8921A4, 0x82818F1281ED449F}, // 1e56 + {0xAFF72D52192B6A0D, 0xA321F2D7226895C7}, // 1e57 + {0x9BF4F8A69F764490, 0xCBEA6F8CEB02BB39}, // 1e58 + {0x02F236D04753D5B4, 0xFEE50B7025C36A08}, // 1e59 + {0x01D762422C946590, 0x9F4F2726179A2245}, // 1e60 + {0x424D3AD2B7B97EF5, 0xC722F0EF9D80AAD6}, // 1e61 + {0xD2E0898765A7DEB2, 0xF8EBAD2B84E0D58B}, // 1e62 + {0x63CC55F49F88EB2F, 0x9B934C3B330C8577}, // 1e63 + {0x3CBF6B71C76B25FB, 0xC2781F49FFCFA6D5}, // 1e64 + {0x8BEF464E3945EF7A, 0xF316271C7FC3908A}, // 1e65 + {0x97758BF0E3CBB5AC, 0x97EDD871CFDA3A56}, // 1e66 + {0x3D52EEED1CBEA317, 0xBDE94E8E43D0C8EC}, // 1e67 + {0x4CA7AAA863EE4BDD, 0xED63A231D4C4FB27}, // 1e68 + {0x8FE8CAA93E74EF6A, 0x945E455F24FB1CF8}, // 1e69 + {0xB3E2FD538E122B44, 0xB975D6B6EE39E436}, // 1e70 + {0x60DBBCA87196B616, 0xE7D34C64A9C85D44}, // 1e71 + {0xBC8955E946FE31CD, 0x90E40FBEEA1D3A4A}, // 1e72 + {0x6BABAB6398BDBE41, 0xB51D13AEA4A488DD}, // 1e73 + {0xC696963C7EED2DD1, 0xE264589A4DCDAB14}, // 1e74 + {0xFC1E1DE5CF543CA2, 0x8D7EB76070A08AEC}, // 1e75 + {0x3B25A55F43294BCB, 0xB0DE65388CC8ADA8}, // 1e76 + {0x49EF0EB713F39EBE, 0xDD15FE86AFFAD912}, // 1e77 + {0x6E3569326C784337, 0x8A2DBF142DFCC7AB}, // 1e78 + {0x49C2C37F07965404, 0xACB92ED9397BF996}, // 1e79 + {0xDC33745EC97BE906, 0xD7E77A8F87DAF7FB}, // 1e80 + {0x69A028BB3DED71A3, 0x86F0AC99B4E8DAFD}, // 1e81 + {0xC40832EA0D68CE0C, 0xA8ACD7C0222311BC}, // 1e82 + {0xF50A3FA490C30190, 0xD2D80DB02AABD62B}, // 1e83 + {0x792667C6DA79E0FA, 0x83C7088E1AAB65DB}, // 1e84 + {0x577001B891185938, 0xA4B8CAB1A1563F52}, // 1e85 + {0xED4C0226B55E6F86, 0xCDE6FD5E09ABCF26}, // 1e86 + {0x544F8158315B05B4, 0x80B05E5AC60B6178}, // 1e87 + {0x696361AE3DB1C721, 0xA0DC75F1778E39D6}, // 1e88 + {0x03BC3A19CD1E38E9, 0xC913936DD571C84C}, // 1e89 + {0x04AB48A04065C723, 0xFB5878494ACE3A5F}, // 1e90 + {0x62EB0D64283F9C76, 0x9D174B2DCEC0E47B}, // 1e91 + {0x3BA5D0BD324F8394, 0xC45D1DF942711D9A}, // 1e92 + {0xCA8F44EC7EE36479, 0xF5746577930D6500}, // 1e93 + {0x7E998B13CF4E1ECB, 0x9968BF6ABBE85F20}, // 1e94 + {0x9E3FEDD8C321A67E, 0xBFC2EF456AE276E8}, // 1e95 + {0xC5CFE94EF3EA101E, 0xEFB3AB16C59B14A2}, // 1e96 + {0xBBA1F1D158724A12, 0x95D04AEE3B80ECE5}, // 1e97 + {0x2A8A6E45AE8EDC97, 0xBB445DA9CA61281F}, // 1e98 + {0xF52D09D71A3293BD, 0xEA1575143CF97226}, // 1e99 + {0x593C2626705F9C56, 0x924D692CA61BE758}, // 1e100 + {0x6F8B2FB00C77836C, 0xB6E0C377CFA2E12E}, // 1e101 + {0x0B6DFB9C0F956447, 0xE498F455C38B997A}, // 1e102 + {0x4724BD4189BD5EAC, 0x8EDF98B59A373FEC}, // 1e103 + {0x58EDEC91EC2CB657, 0xB2977EE300C50FE7}, // 1e104 + {0x2F2967B66737E3ED, 0xDF3D5E9BC0F653E1}, // 1e105 + {0xBD79E0D20082EE74, 0x8B865B215899F46C}, // 1e106 + {0xECD8590680A3AA11, 0xAE67F1E9AEC07187}, // 1e107 + {0xE80E6F4820CC9495, 0xDA01EE641A708DE9}, // 1e108 + {0x3109058D147FDCDD, 0x884134FE908658B2}, // 1e109 + {0xBD4B46F0599FD415, 0xAA51823E34A7EEDE}, // 1e110 + {0x6C9E18AC7007C91A, 0xD4E5E2CDC1D1EA96}, // 1e111 + {0x03E2CF6BC604DDB0, 0x850FADC09923329E}, // 1e112 + {0x84DB8346B786151C, 0xA6539930BF6BFF45}, // 1e113 + {0xE612641865679A63, 0xCFE87F7CEF46FF16}, // 1e114 + {0x4FCB7E8F3F60C07E, 0x81F14FAE158C5F6E}, // 1e115 + {0xE3BE5E330F38F09D, 0xA26DA3999AEF7749}, // 1e116 + {0x5CADF5BFD3072CC5, 0xCB090C8001AB551C}, // 1e117 + {0x73D9732FC7C8F7F6, 0xFDCB4FA002162A63}, // 1e118 + {0x2867E7FDDCDD9AFA, 0x9E9F11C4014DDA7E}, // 1e119 + {0xB281E1FD541501B8, 0xC646D63501A1511D}, // 1e120 + {0x1F225A7CA91A4226, 0xF7D88BC24209A565}, // 1e121 + {0x3375788DE9B06958, 0x9AE757596946075F}, // 1e122 + {0x0052D6B1641C83AE, 0xC1A12D2FC3978937}, // 1e123 + {0xC0678C5DBD23A49A, 0xF209787BB47D6B84}, // 1e124 + {0xF840B7BA963646E0, 0x9745EB4D50CE6332}, // 1e125 + {0xB650E5A93BC3D898, 0xBD176620A501FBFF}, // 1e126 + {0xA3E51F138AB4CEBE, 0xEC5D3FA8CE427AFF}, // 1e127 + {0xC66F336C36B10137, 0x93BA47C980E98CDF}, // 1e128 + {0xB80B0047445D4184, 0xB8A8D9BBE123F017}, // 1e129 + {0xA60DC059157491E5, 0xE6D3102AD96CEC1D}, // 1e130 + {0x87C89837AD68DB2F, 0x9043EA1AC7E41392}, // 1e131 + {0x29BABE4598C311FB, 0xB454E4A179DD1877}, // 1e132 + {0xF4296DD6FEF3D67A, 0xE16A1DC9D8545E94}, // 1e133 + {0x1899E4A65F58660C, 0x8CE2529E2734BB1D}, // 1e134 + {0x5EC05DCFF72E7F8F, 0xB01AE745B101E9E4}, // 1e135 + {0x76707543F4FA1F73, 0xDC21A1171D42645D}, // 1e136 + {0x6A06494A791C53A8, 0x899504AE72497EBA}, // 1e137 + {0x0487DB9D17636892, 0xABFA45DA0EDBDE69}, // 1e138 + {0x45A9D2845D3C42B6, 0xD6F8D7509292D603}, // 1e139 + {0x0B8A2392BA45A9B2, 0x865B86925B9BC5C2}, // 1e140 + {0x8E6CAC7768D7141E, 0xA7F26836F282B732}, // 1e141 + {0x3207D795430CD926, 0xD1EF0244AF2364FF}, // 1e142 + {0x7F44E6BD49E807B8, 0x8335616AED761F1F}, // 1e143 + {0x5F16206C9C6209A6, 0xA402B9C5A8D3A6E7}, // 1e144 + {0x36DBA887C37A8C0F, 0xCD036837130890A1}, // 1e145 + {0xC2494954DA2C9789, 0x802221226BE55A64}, // 1e146 + {0xF2DB9BAA10B7BD6C, 0xA02AA96B06DEB0FD}, // 1e147 + {0x6F92829494E5ACC7, 0xC83553C5C8965D3D}, // 1e148 + {0xCB772339BA1F17F9, 0xFA42A8B73ABBF48C}, // 1e149 + {0xFF2A760414536EFB, 0x9C69A97284B578D7}, // 1e150 + {0xFEF5138519684ABA, 0xC38413CF25E2D70D}, // 1e151 + {0x7EB258665FC25D69, 0xF46518C2EF5B8CD1}, // 1e152 + {0xEF2F773FFBD97A61, 0x98BF2F79D5993802}, // 1e153 + {0xAAFB550FFACFD8FA, 0xBEEEFB584AFF8603}, // 1e154 + {0x95BA2A53F983CF38, 0xEEAABA2E5DBF6784}, // 1e155 + {0xDD945A747BF26183, 0x952AB45CFA97A0B2}, // 1e156 + {0x94F971119AEEF9E4, 0xBA756174393D88DF}, // 1e157 + {0x7A37CD5601AAB85D, 0xE912B9D1478CEB17}, // 1e158 + {0xAC62E055C10AB33A, 0x91ABB422CCB812EE}, // 1e159 + {0x577B986B314D6009, 0xB616A12B7FE617AA}, // 1e160 + {0xED5A7E85FDA0B80B, 0xE39C49765FDF9D94}, // 1e161 + {0x14588F13BE847307, 0x8E41ADE9FBEBC27D}, // 1e162 + {0x596EB2D8AE258FC8, 0xB1D219647AE6B31C}, // 1e163 + {0x6FCA5F8ED9AEF3BB, 0xDE469FBD99A05FE3}, // 1e164 + {0x25DE7BB9480D5854, 0x8AEC23D680043BEE}, // 1e165 + {0xAF561AA79A10AE6A, 0xADA72CCC20054AE9}, // 1e166 + {0x1B2BA1518094DA04, 0xD910F7FF28069DA4}, // 1e167 + {0x90FB44D2F05D0842, 0x87AA9AFF79042286}, // 1e168 + {0x353A1607AC744A53, 0xA99541BF57452B28}, // 1e169 + {0x42889B8997915CE8, 0xD3FA922F2D1675F2}, // 1e170 + {0x69956135FEBADA11, 0x847C9B5D7C2E09B7}, // 1e171 + {0x43FAB9837E699095, 0xA59BC234DB398C25}, // 1e172 + {0x94F967E45E03F4BB, 0xCF02B2C21207EF2E}, // 1e173 + {0x1D1BE0EEBAC278F5, 0x8161AFB94B44F57D}, // 1e174 + {0x6462D92A69731732, 0xA1BA1BA79E1632DC}, // 1e175 + {0x7D7B8F7503CFDCFE, 0xCA28A291859BBF93}, // 1e176 + {0x5CDA735244C3D43E, 0xFCB2CB35E702AF78}, // 1e177 + {0x3A0888136AFA64A7, 0x9DEFBF01B061ADAB}, // 1e178 + {0x088AAA1845B8FDD0, 0xC56BAEC21C7A1916}, // 1e179 + {0x8AAD549E57273D45, 0xF6C69A72A3989F5B}, // 1e180 + {0x36AC54E2F678864B, 0x9A3C2087A63F6399}, // 1e181 + {0x84576A1BB416A7DD, 0xC0CB28A98FCF3C7F}, // 1e182 + {0x656D44A2A11C51D5, 0xF0FDF2D3F3C30B9F}, // 1e183 + {0x9F644AE5A4B1B325, 0x969EB7C47859E743}, // 1e184 + {0x873D5D9F0DDE1FEE, 0xBC4665B596706114}, // 1e185 + {0xA90CB506D155A7EA, 0xEB57FF22FC0C7959}, // 1e186 + {0x09A7F12442D588F2, 0x9316FF75DD87CBD8}, // 1e187 + {0x0C11ED6D538AEB2F, 0xB7DCBF5354E9BECE}, // 1e188 + {0x8F1668C8A86DA5FA, 0xE5D3EF282A242E81}, // 1e189 + {0xF96E017D694487BC, 0x8FA475791A569D10}, // 1e190 + {0x37C981DCC395A9AC, 0xB38D92D760EC4455}, // 1e191 + {0x85BBE253F47B1417, 0xE070F78D3927556A}, // 1e192 + {0x93956D7478CCEC8E, 0x8C469AB843B89562}, // 1e193 + {0x387AC8D1970027B2, 0xAF58416654A6BABB}, // 1e194 + {0x06997B05FCC0319E, 0xDB2E51BFE9D0696A}, // 1e195 + {0x441FECE3BDF81F03, 0x88FCF317F22241E2}, // 1e196 + {0xD527E81CAD7626C3, 0xAB3C2FDDEEAAD25A}, // 1e197 + {0x8A71E223D8D3B074, 0xD60B3BD56A5586F1}, // 1e198 + {0xF6872D5667844E49, 0x85C7056562757456}, // 1e199 + {0xB428F8AC016561DB, 0xA738C6BEBB12D16C}, // 1e200 + {0xE13336D701BEBA52, 0xD106F86E69D785C7}, // 1e201 + {0xECC0024661173473, 0x82A45B450226B39C}, // 1e202 + {0x27F002D7F95D0190, 0xA34D721642B06084}, // 1e203 + {0x31EC038DF7B441F4, 0xCC20CE9BD35C78A5}, // 1e204 + {0x7E67047175A15271, 0xFF290242C83396CE}, // 1e205 + {0x0F0062C6E984D386, 0x9F79A169BD203E41}, // 1e206 + {0x52C07B78A3E60868, 0xC75809C42C684DD1}, // 1e207 + {0xA7709A56CCDF8A82, 0xF92E0C3537826145}, // 1e208 + {0x88A66076400BB691, 0x9BBCC7A142B17CCB}, // 1e209 + {0x6ACFF893D00EA435, 0xC2ABF989935DDBFE}, // 1e210 + {0x0583F6B8C4124D43, 0xF356F7EBF83552FE}, // 1e211 + {0xC3727A337A8B704A, 0x98165AF37B2153DE}, // 1e212 + {0x744F18C0592E4C5C, 0xBE1BF1B059E9A8D6}, // 1e213 + {0x1162DEF06F79DF73, 0xEDA2EE1C7064130C}, // 1e214 + {0x8ADDCB5645AC2BA8, 0x9485D4D1C63E8BE7}, // 1e215 + {0x6D953E2BD7173692, 0xB9A74A0637CE2EE1}, // 1e216 + {0xC8FA8DB6CCDD0437, 0xE8111C87C5C1BA99}, // 1e217 + {0x1D9C9892400A22A2, 0x910AB1D4DB9914A0}, // 1e218 + {0x2503BEB6D00CAB4B, 0xB54D5E4A127F59C8}, // 1e219 + {0x2E44AE64840FD61D, 0xE2A0B5DC971F303A}, // 1e220 + {0x5CEAECFED289E5D2, 0x8DA471A9DE737E24}, // 1e221 + {0x7425A83E872C5F47, 0xB10D8E1456105DAD}, // 1e222 + {0xD12F124E28F77719, 0xDD50F1996B947518}, // 1e223 + {0x82BD6B70D99AAA6F, 0x8A5296FFE33CC92F}, // 1e224 + {0x636CC64D1001550B, 0xACE73CBFDC0BFB7B}, // 1e225 + {0x3C47F7E05401AA4E, 0xD8210BEFD30EFA5A}, // 1e226 + {0x65ACFAEC34810A71, 0x8714A775E3E95C78}, // 1e227 + {0x7F1839A741A14D0D, 0xA8D9D1535CE3B396}, // 1e228 + {0x1EDE48111209A050, 0xD31045A8341CA07C}, // 1e229 + {0x934AED0AAB460432, 0x83EA2B892091E44D}, // 1e230 + {0xF81DA84D5617853F, 0xA4E4B66B68B65D60}, // 1e231 + {0x36251260AB9D668E, 0xCE1DE40642E3F4B9}, // 1e232 + {0xC1D72B7C6B426019, 0x80D2AE83E9CE78F3}, // 1e233 + {0xB24CF65B8612F81F, 0xA1075A24E4421730}, // 1e234 + {0xDEE033F26797B627, 0xC94930AE1D529CFC}, // 1e235 + {0x169840EF017DA3B1, 0xFB9B7CD9A4A7443C}, // 1e236 + {0x8E1F289560EE864E, 0x9D412E0806E88AA5}, // 1e237 + {0xF1A6F2BAB92A27E2, 0xC491798A08A2AD4E}, // 1e238 + {0xAE10AF696774B1DB, 0xF5B5D7EC8ACB58A2}, // 1e239 + {0xACCA6DA1E0A8EF29, 0x9991A6F3D6BF1765}, // 1e240 + {0x17FD090A58D32AF3, 0xBFF610B0CC6EDD3F}, // 1e241 + {0xDDFC4B4CEF07F5B0, 0xEFF394DCFF8A948E}, // 1e242 + {0x4ABDAF101564F98E, 0x95F83D0A1FB69CD9}, // 1e243 + {0x9D6D1AD41ABE37F1, 0xBB764C4CA7A4440F}, // 1e244 + {0x84C86189216DC5ED, 0xEA53DF5FD18D5513}, // 1e245 + {0x32FD3CF5B4E49BB4, 0x92746B9BE2F8552C}, // 1e246 + {0x3FBC8C33221DC2A1, 0xB7118682DBB66A77}, // 1e247 + {0x0FABAF3FEAA5334A, 0xE4D5E82392A40515}, // 1e248 + {0x29CB4D87F2A7400E, 0x8F05B1163BA6832D}, // 1e249 + {0x743E20E9EF511012, 0xB2C71D5BCA9023F8}, // 1e250 + {0x914DA9246B255416, 0xDF78E4B2BD342CF6}, // 1e251 + {0x1AD089B6C2F7548E, 0x8BAB8EEFB6409C1A}, // 1e252 + {0xA184AC2473B529B1, 0xAE9672ABA3D0C320}, // 1e253 + {0xC9E5D72D90A2741E, 0xDA3C0F568CC4F3E8}, // 1e254 + {0x7E2FA67C7A658892, 0x8865899617FB1871}, // 1e255 + {0xDDBB901B98FEEAB7, 0xAA7EEBFB9DF9DE8D}, // 1e256 + {0x552A74227F3EA565, 0xD51EA6FA85785631}, // 1e257 + {0xD53A88958F87275F, 0x8533285C936B35DE}, // 1e258 + {0x8A892ABAF368F137, 0xA67FF273B8460356}, // 1e259 + {0x2D2B7569B0432D85, 0xD01FEF10A657842C}, // 1e260 + {0x9C3B29620E29FC73, 0x8213F56A67F6B29B}, // 1e261 + {0x8349F3BA91B47B8F, 0xA298F2C501F45F42}, // 1e262 + {0x241C70A936219A73, 0xCB3F2F7642717713}, // 1e263 + {0xED238CD383AA0110, 0xFE0EFB53D30DD4D7}, // 1e264 + {0xF4363804324A40AA, 0x9EC95D1463E8A506}, // 1e265 + {0xB143C6053EDCD0D5, 0xC67BB4597CE2CE48}, // 1e266 + {0xDD94B7868E94050A, 0xF81AA16FDC1B81DA}, // 1e267 + {0xCA7CF2B4191C8326, 0x9B10A4E5E9913128}, // 1e268 + {0xFD1C2F611F63A3F0, 0xC1D4CE1F63F57D72}, // 1e269 + {0xBC633B39673C8CEC, 0xF24A01A73CF2DCCF}, // 1e270 + {0xD5BE0503E085D813, 0x976E41088617CA01}, // 1e271 + {0x4B2D8644D8A74E18, 0xBD49D14AA79DBC82}, // 1e272 + {0xDDF8E7D60ED1219E, 0xEC9C459D51852BA2}, // 1e273 + {0xCABB90E5C942B503, 0x93E1AB8252F33B45}, // 1e274 + {0x3D6A751F3B936243, 0xB8DA1662E7B00A17}, // 1e275 + {0x0CC512670A783AD4, 0xE7109BFBA19C0C9D}, // 1e276 + {0x27FB2B80668B24C5, 0x906A617D450187E2}, // 1e277 + {0xB1F9F660802DEDF6, 0xB484F9DC9641E9DA}, // 1e278 + {0x5E7873F8A0396973, 0xE1A63853BBD26451}, // 1e279 + {0xDB0B487B6423E1E8, 0x8D07E33455637EB2}, // 1e280 + {0x91CE1A9A3D2CDA62, 0xB049DC016ABC5E5F}, // 1e281 + {0x7641A140CC7810FB, 0xDC5C5301C56B75F7}, // 1e282 + {0xA9E904C87FCB0A9D, 0x89B9B3E11B6329BA}, // 1e283 + {0x546345FA9FBDCD44, 0xAC2820D9623BF429}, // 1e284 + {0xA97C177947AD4095, 0xD732290FBACAF133}, // 1e285 + {0x49ED8EABCCCC485D, 0x867F59A9D4BED6C0}, // 1e286 + {0x5C68F256BFFF5A74, 0xA81F301449EE8C70}, // 1e287 + {0x73832EEC6FFF3111, 0xD226FC195C6A2F8C}, // 1e288 + {0xC831FD53C5FF7EAB, 0x83585D8FD9C25DB7}, // 1e289 + {0xBA3E7CA8B77F5E55, 0xA42E74F3D032F525}, // 1e290 + {0x28CE1BD2E55F35EB, 0xCD3A1230C43FB26F}, // 1e291 + {0x7980D163CF5B81B3, 0x80444B5E7AA7CF85}, // 1e292 + {0xD7E105BCC332621F, 0xA0555E361951C366}, // 1e293 + {0x8DD9472BF3FEFAA7, 0xC86AB5C39FA63440}, // 1e294 + {0xB14F98F6F0FEB951, 0xFA856334878FC150}, // 1e295 + {0x6ED1BF9A569F33D3, 0x9C935E00D4B9D8D2}, // 1e296 + {0x0A862F80EC4700C8, 0xC3B8358109E84F07}, // 1e297 + {0xCD27BB612758C0FA, 0xF4A642E14C6262C8}, // 1e298 + {0x8038D51CB897789C, 0x98E7E9CCCFBD7DBD}, // 1e299 + {0xE0470A63E6BD56C3, 0xBF21E44003ACDD2C}, // 1e300 + {0x1858CCFCE06CAC74, 0xEEEA5D5004981478}, // 1e301 + {0x0F37801E0C43EBC8, 0x95527A5202DF0CCB}, // 1e302 + {0xD30560258F54E6BA, 0xBAA718E68396CFFD}, // 1e303 + {0x47C6B82EF32A2069, 0xE950DF20247C83FD}, // 1e304 + {0x4CDC331D57FA5441, 0x91D28B7416CDD27E}, // 1e305 + {0xE0133FE4ADF8E952, 0xB6472E511C81471D}, // 1e306 + {0x58180FDDD97723A6, 0xE3D8F9E563A198E5}, // 1e307 + {0x570F09EAA7EA7648, 0x8E679C2F5E44FF8F}, // 1e308 + {0x2CD2CC6551E513DA, 0xB201833B35D63F73}, // 1e309 + {0xF8077F7EA65E58D1, 0xDE81E40A034BCF4F}, // 1e310 + {0xFB04AFAF27FAF782, 0x8B112E86420F6191}, // 1e311 + {0x79C5DB9AF1F9B563, 0xADD57A27D29339F6}, // 1e312 + {0x18375281AE7822BC, 0xD94AD8B1C7380874}, // 1e313 + {0x8F2293910D0B15B5, 0x87CEC76F1C830548}, // 1e314 + {0xB2EB3875504DDB22, 0xA9C2794AE3A3C69A}, // 1e315 + {0x5FA60692A46151EB, 0xD433179D9C8CB841}, // 1e316 + {0xDBC7C41BA6BCD333, 0x849FEEC281D7F328}, // 1e317 + {0x12B9B522906C0800, 0xA5C7EA73224DEFF3}, // 1e318 + {0xD768226B34870A00, 0xCF39E50FEAE16BEF}, // 1e319 + {0xE6A1158300D46640, 0x81842F29F2CCE375}, // 1e320 + {0x60495AE3C1097FD0, 0xA1E53AF46F801C53}, // 1e321 + {0x385BB19CB14BDFC4, 0xCA5E89B18B602368}, // 1e322 + {0x46729E03DD9ED7B5, 0xFCF62C1DEE382C42}, // 1e323 + {0x6C07A2C26A8346D1, 0x9E19DB92B4E31BA9}, // 1e324 + {0xC7098B7305241885, 0xC5A05277621BE293}, // 1e325 + {0xB8CBEE4FC66D1EA7, 0xF70867153AA2DB38}, // 1e326 + {0x737F74F1DC043328, 0x9A65406D44A5C903}, // 1e327 + {0x505F522E53053FF2, 0xC0FE908895CF3B44}, // 1e328 + {0x647726B9E7C68FEF, 0xF13E34AABB430A15}, // 1e329 + {0x5ECA783430DC19F5, 0x96C6E0EAB509E64D}, // 1e330 + {0xB67D16413D132072, 0xBC789925624C5FE0}, // 1e331 + {0xE41C5BD18C57E88F, 0xEB96BF6EBADF77D8}, // 1e332 + {0x8E91B962F7B6F159, 0x933E37A534CBAAE7}, // 1e333 + {0x723627BBB5A4ADB0, 0xB80DC58E81FE95A1}, // 1e334 + {0xCEC3B1AAA30DD91C, 0xE61136F2227E3B09}, // 1e335 + {0x213A4F0AA5E8A7B1, 0x8FCAC257558EE4E6}, // 1e336 + {0xA988E2CD4F62D19D, 0xB3BD72ED2AF29E1F}, // 1e337 + {0x93EB1B80A33B8605, 0xE0ACCFA875AF45A7}, // 1e338 + {0xBC72F130660533C3, 0x8C6C01C9498D8B88}, // 1e339 + {0xEB8FAD7C7F8680B4, 0xAF87023B9BF0EE6A}, // 1e340 + {0xA67398DB9F6820E1, 0xDB68C2CA82ED2A05}, // 1e341 + {0x88083F8943A1148C, 0x892179BE91D43A43}, // 1e342 + {0x6A0A4F6B948959B0, 0xAB69D82E364948D4}, // 1e343 + {0x848CE34679ABB01C, 0xD6444E39C3DB9B09}, // 1e344 + {0xF2D80E0C0C0B4E11, 0x85EAB0E41A6940E5}, // 1e345 + {0x6F8E118F0F0E2195, 0xA7655D1D2103911F}, // 1e346 + {0x4B7195F2D2D1A9FB, 0xD13EB46469447567}, // 1e347 +} diff --git a/go/mysql/fastparse/fastparse.go b/go/mysql/fastparse/fastparse.go index a669a584d72..3601e0ee1de 100644 --- a/go/mysql/fastparse/fastparse.go +++ b/go/mysql/fastparse/fastparse.go @@ -22,8 +22,6 @@ import ( "fmt" "math" "strconv" - - "vitess.io/vitess/go/hack" ) func ParseUint64(s string, base int) (uint64, error) { @@ -259,9 +257,8 @@ func ParseFloat64(s string) (float64, error) { ws := i // We only care to parse as many of the initial float characters of the - // string as possible. This functionality is implemented in the `strconv` package - // of the standard library, but not exposed, so we hook into it. - val, l, err := hack.Atof64(s[ws:]) + // string as possible. + val, l, err := Atof64(s[ws:]) for l < len(s[ws:]) { if !isSpace(s[ws+uint(l)]) { break diff --git a/go/mysql/fastparse/fastparse_test.go b/go/mysql/fastparse/fastparse_test.go index 5ee87a617d1..cf00c53a21d 100644 --- a/go/mysql/fastparse/fastparse_test.go +++ b/go/mysql/fastparse/fastparse_test.go @@ -569,7 +569,7 @@ func TestParseFloat64(t *testing.T) { { input: "-", expected: 0.0, - err: `strconv.ParseFloat: parsing "-": invalid syntax`, + err: strconv.ErrSyntax.Error(), }, { input: " 10", diff --git a/go/vt/vtgate/evalengine/weights.go b/go/vt/vtgate/evalengine/weights.go index 3eb9aa290c5..ecf967787fc 100644 --- a/go/vt/vtgate/evalengine/weights.go +++ b/go/vt/vtgate/evalengine/weights.go @@ -20,11 +20,11 @@ import ( "encoding/binary" "math" - "vitess.io/vitess/go/hack" "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/mysql/collations/charset" "vitess.io/vitess/go/mysql/collations/colldata" "vitess.io/vitess/go/mysql/decimal" + "vitess.io/vitess/go/mysql/fastparse" "vitess.io/vitess/go/mysql/json" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" @@ -282,14 +282,14 @@ func TinyWeighter(f *querypb.Field, collation collations.ID) func(v *sqltypes.Va if v.IsNull() { return } - // To generate a 32-bit weight string of the decimal, we'll just attempt a fast 32bit atof parse + // To generate a 32-bit weight string of the decimal, we'll just attempt a fast atof parse // of its contents. This can definitely fail for many corner cases, but that's OK: we'll just fall // back to a full decimal comparison in those cases. - fl, _, err := hack.Atof32(v.RawStr()) + fl, _, err := fastparse.Atof64(v.RawStr()) if err != nil { return } - raw := math.Float32bits(fl) + raw := math.Float32bits(float32(fl)) if raw&(1<<31) != 0 { raw = ^raw } else { From bcf6da6b70d15c4dadd7a73d4cdff2ba682c72d6 Mon Sep 17 00:00:00 2001 From: Florent Poinsard <35779988+frouioui@users.noreply.github.com> Date: Mon, 10 Jun 2024 11:33:37 -0600 Subject: [PATCH 13/40] Remove DCO workaround (#16087) Signed-off-by: Florent Poinsard --- .github/workflows/dco.yml | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 .github/workflows/dco.yml diff --git a/.github/workflows/dco.yml b/.github/workflows/dco.yml deleted file mode 100644 index eb377b4dd42..00000000000 --- a/.github/workflows/dco.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: DCO -on: - pull_request: - push: - branches: - - main - -jobs: - check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Setup Python 3.x - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Check DCO - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - pip3 install -U dco-check - dco-check --verbose \ No newline at end of file From 6fb0f0e0f507e6e6e829783ae840fd4063eca9e2 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 10 Jun 2024 21:29:41 +0300 Subject: [PATCH 14/40] `schemadiff`: improved diff ordering with various foreign key strategies (#16081) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/schemadiff/schema.go | 2 +- go/vt/schemadiff/schema_diff.go | 82 +++++++--- go/vt/schemadiff/schema_diff_test.go | 216 ++++++++++++++++++++++++++- go/vt/schemadiff/types.go | 1 + 4 files changed, 276 insertions(+), 25 deletions(-) diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index f4cc0b67217..1738b9a4836 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -234,7 +234,7 @@ func (s *Schema) normalize(hints *DiffHints) error { // already handled; skip continue } - // Not handled. Is this view dependent on already handled objects? + // Not handled. Does this table reference an already handled table? referencedTableNames := getForeignKeyParentTableNames(t.CreateTable) if len(referencedTableNames) > 0 { s.foreignKeyChildren = append(s.foreignKeyChildren, t) diff --git a/go/vt/schemadiff/schema_diff.go b/go/vt/schemadiff/schema_diff.go index 3fbc1e6c9d3..60285265986 100644 --- a/go/vt/schemadiff/schema_diff.go +++ b/go/vt/schemadiff/schema_diff.go @@ -88,27 +88,27 @@ Modified to have an early break // permutateDiffs calls `callback` with each permutation of a. If the function returns `true`, that means // the callback has returned `true` for an early break, thus possibly not all permutations have been evaluated. -func permutateDiffs(ctx context.Context, diffs []EntityDiff, callback func([]EntityDiff) (earlyBreak bool)) (earlyBreak bool, err error) { +func permutateDiffs(ctx context.Context, diffs []EntityDiff, hints *DiffHints, callback func([]EntityDiff, *DiffHints) (earlyBreak bool)) (earlyBreak bool, err error) { if len(diffs) == 0 { return false, nil } // Sort by a heuristic (DROPs first, ALTERs next, CREATEs last). This ordering is then used first in the permutation // search and serves as seed for the rest of permutations. - return permDiff(ctx, diffs, callback, 0) + return permDiff(ctx, diffs, hints, callback, 0) } // permDiff is a recursive function to permutate given `a` and call `callback` for each permutation. // If `callback` returns `true`, then so does this function, and this indicates a request for an early // break, in which case this function will not be called again. -func permDiff(ctx context.Context, a []EntityDiff, callback func([]EntityDiff) (earlyBreak bool), i int) (earlyBreak bool, err error) { +func permDiff(ctx context.Context, a []EntityDiff, hints *DiffHints, callback func([]EntityDiff, *DiffHints) (earlyBreak bool), i int) (earlyBreak bool, err error) { if err := ctx.Err(); err != nil { return true, err // early break } if i > len(a) { - return callback(a), nil + return callback(a, hints), nil } - if brk, err := permDiff(ctx, a, callback, i+1); brk { + if brk, err := permDiff(ctx, a, hints, callback, i+1); brk { return true, err } for j := i + 1; j < len(a); j++ { @@ -150,7 +150,7 @@ func permDiff(ctx context.Context, a []EntityDiff, callback func([]EntityDiff) ( } // End of optimization a[i], a[j] = a[j], a[i] - if brk, err := permDiff(ctx, a, callback, i+1); brk { + if brk, err := permDiff(ctx, a, hints, callback, i+1); brk { return true, err } a[i], a[j] = a[j], a[i] @@ -315,21 +315,65 @@ func (d *SchemaDiff) OrderedDiffs(ctx context.Context) ([]EntityDiff, error) { // We will now permutate the diffs in this equivalence class, and hopefully find // a valid permutation (one where if we apply the diffs in-order, the schema remains valid throughout the process) - foundValidPathForClass, err := permutateDiffs(ctx, classDiffs, func(permutatedDiffs []EntityDiff) bool { - permutationSchema := lastGoodSchema.copy() - // We want to apply the changes one by one, and validate the schema after each change - for i := range permutatedDiffs { - // apply inline - if err := permutationSchema.apply(permutatedDiffs[i:i+1], d.hints); err != nil { - // permutation is invalid - return false // continue searching + tryPermutateDiffs := func(hints *DiffHints) (bool, error) { + return permutateDiffs(ctx, classDiffs, hints, func(permutatedDiffs []EntityDiff, hints *DiffHints) bool { + permutationSchema := lastGoodSchema.copy() + // We want to apply the changes one by one, and validate the schema after each change + for i := range permutatedDiffs { + // apply inline + applyHints := hints + if hints.ForeignKeyCheckStrategy == ForeignKeyCheckStrategyCreateTableFirst { + // This is a strategy that handles foreign key loops in a heuristic way. + // It means: we allow for the very first change to be a CREATE TABLE, and ignore + // any dependencies that CREATE TABLE may have. But then, we require the rest of + // changes to have a strict order. + overrideHints := *hints + overrideHints.ForeignKeyCheckStrategy = ForeignKeyCheckStrategyStrict + if i == 0 { + if _, ok := permutatedDiffs[i].(*CreateTableEntityDiff); ok { + overrideHints.ForeignKeyCheckStrategy = ForeignKeyCheckStrategyIgnore + } + } + applyHints = &overrideHints + } + if err := permutationSchema.apply(permutatedDiffs[i:i+1], applyHints); err != nil { + // permutation is invalid + return false // continue searching + } + } + + // Good news, we managed to apply all of the permutations! + orderedDiffs = append(orderedDiffs, permutatedDiffs...) + lastGoodSchema = permutationSchema + return true // early break! No need to keep searching + }) + } + // We prefer stricter strategy, because that gives best chance of finding a valid path. + // So on best effort basis, we try to find a valid path starting with the strictest strategy, easing + // to more relaxed ones, but never below the preconfigured. + // For example, if the preconfigured strategy is "strict", we will try "strict" and then stop. + // If the preconfigured strategy is "create-table-first", we will try "strict", then "create-table-first", then stop. + tryPermutateDiffsAcrossStrategies := func() (found bool, err error) { + for _, fkStrategy := range []int{ForeignKeyCheckStrategyStrict, ForeignKeyCheckStrategyCreateTableFirst, ForeignKeyCheckStrategyIgnore} { + hints := *d.hints + hints.ForeignKeyCheckStrategy = fkStrategy + found, err = tryPermutateDiffs(&hints) + if fkStrategy == d.hints.ForeignKeyCheckStrategy { + // end of the line. + return found, err + } + if err != nil { + // No luck with this strategy, let's try the next one. + continue + } + if found { + // Good news! + return true, nil } } - // Good news, we managed to apply all of the permutations! - orderedDiffs = append(orderedDiffs, permutatedDiffs...) - lastGoodSchema = permutationSchema - return true // early break! No need to keep searching - }) + return found, err + } + foundValidPathForClass, err := tryPermutateDiffsAcrossStrategies() if err != nil { return nil, err } diff --git a/go/vt/schemadiff/schema_diff_test.go b/go/vt/schemadiff/schema_diff_test.go index 4d6ca522d1e..8adc4fc8d68 100644 --- a/go/vt/schemadiff/schema_diff_test.go +++ b/go/vt/schemadiff/schema_diff_test.go @@ -195,7 +195,7 @@ func TestPermutations(t *testing.T) { allDiffs := schemaDiff.UnorderedDiffs() originalSingleString := toSingleString(allDiffs) numEquals := 0 - earlyBreak, err := permutateDiffs(ctx, allDiffs, func(pdiffs []EntityDiff) (earlyBreak bool) { + earlyBreak, err := permutateDiffs(ctx, allDiffs, hints, func(pdiffs []EntityDiff, hints *DiffHints) (earlyBreak bool) { defer func() { iteration++ }() // cover all permutations singleString := toSingleString(pdiffs) @@ -218,7 +218,7 @@ func TestPermutations(t *testing.T) { allPerms := map[string]bool{} allDiffs := schemaDiff.UnorderedDiffs() originalSingleString := toSingleString(allDiffs) - earlyBreak, err := permutateDiffs(ctx, allDiffs, func(pdiffs []EntityDiff) (earlyBreak bool) { + earlyBreak, err := permutateDiffs(ctx, allDiffs, hints, func(pdiffs []EntityDiff, hints *DiffHints) (earlyBreak bool) { // Single visit allPerms[toSingleString(pdiffs)] = true // First permutation should be the same as original @@ -244,8 +244,9 @@ func TestPermutationsContext(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) cancel() + hints := &DiffHints{RangeRotationStrategy: RangeRotationDistinctStatements} allDiffs := []EntityDiff{&DropViewEntityDiff{}} - earlyBreak, err := permutateDiffs(ctx, allDiffs, func(pdiffs []EntityDiff) (earlyBreak bool) { + earlyBreak, err := permutateDiffs(ctx, allDiffs, hints, func(pdiffs []EntityDiff, hints *DiffHints) (earlyBreak bool) { return false }) assert.True(t, earlyBreak) // proves that termination was due to context cancel @@ -678,6 +679,142 @@ func TestSchemaDiff(t *testing.T) { instantCapability: InstantDDLCapabilityIrrelevant, fkStrategy: ForeignKeyCheckStrategyIgnore, }, + { + name: "two table cycle with create, strict", + fromQueries: append(createQueries, + "create table t11 (id int primary key, i0 int);", + ), + toQueries: append( + createQueries, + "create table t12 (id int primary key, i int, constraint f1201 foreign key (i) references t11 (i) on delete set null);", + "create table t11 (id int primary key, i0 int, i int, key (i), constraint f1101 foreign key (i) references t12 (id) on delete restrict);", + ), + expectDiffs: 2, + expectDeps: 2, + sequential: true, + instantCapability: InstantDDLCapabilityIrrelevant, + fkStrategy: ForeignKeyCheckStrategyStrict, + expectOrderedError: "no valid applicable order for diffs", + }, + { + name: "two table cycle with create, strict, changed lexicographic order", + fromQueries: append(createQueries, + "create table t12 (id int primary key, i0 int);", + ), + toQueries: append( + createQueries, + "create table t11 (id int primary key, i int, constraint f1201 foreign key (i) references t12 (i) on delete set null);", + "create table t12 (id int primary key, i0 int, i int, key (i), constraint f1101 foreign key (i) references t11 (id) on delete restrict);", + ), + expectDiffs: 2, + expectDeps: 2, + sequential: true, + instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyStrict, + expectOrderedError: "no valid applicable order for diffs", + }, + { + name: "two table cycle with create, ignore", + fromQueries: append(createQueries, + "create table t11 (id int primary key, i0 int);", + ), + toQueries: append( + createQueries, + "create table t12 (id int primary key, i int, constraint f1201 foreign key (i) references t11 (i) on delete set null);", + "create table t11 (id int primary key, i0 int, i int, key (i), constraint f1101 foreign key (i) references t12 (id) on delete restrict);", + ), + expectDiffs: 2, + expectDeps: 2, + entityOrder: []string{"t11", "t12"}, + sequential: true, + instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyIgnore, + }, + { + name: "two table cycle with create, ignore, changed lexicographic order", + fromQueries: append(createQueries, + "create table t12 (id int primary key, i0 int);", + ), + toQueries: append( + createQueries, + "create table t11 (id int primary key, i int, constraint f1201 foreign key (i) references t12 (i) on delete set null);", + "create table t12 (id int primary key, i0 int, i int, key (i), constraint f1101 foreign key (i) references t11 (id) on delete restrict);", + ), + expectDiffs: 2, + expectDeps: 2, + entityOrder: []string{"t12", "t11"}, + sequential: true, + instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyIgnore, + }, + { + name: "two table cycle with create, existing column, ignore", + fromQueries: append(createQueries, + "create table t12 (id int primary key, i int, key (i));", + ), + toQueries: append( + createQueries, + "create table t11 (id int primary key, i int, constraint f1201 foreign key (i) references t12 (i) on delete set null);", + "create table t12 (id int primary key, i int, key (i), constraint f1101 foreign key (i) references t11 (id) on delete restrict);", + ), + expectDiffs: 2, + expectDeps: 2, + entityOrder: []string{"t11", "t12"}, + sequential: true, + instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyIgnore, + }, + { + name: "two table cycle with create, existing column, changed lexicographic order, ignore", + fromQueries: append(createQueries, + "create table t11 (id int primary key, i int, key (i));", + ), + toQueries: append( + createQueries, + "create table t12 (id int primary key, i int, constraint f1201 foreign key (i) references t11 (i) on delete set null);", + "create table t11 (id int primary key, i int, key (i), constraint f1101 foreign key (i) references t12 (id) on delete restrict);", + ), + expectDiffs: 2, + expectDeps: 2, + entityOrder: []string{"t12", "t11"}, + sequential: true, + instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyIgnore, + }, + { + name: "two table cycle with create, create table first", + fromQueries: append(createQueries, + "create table t12 (id int primary key, i int, key (i));", + ), + toQueries: append( + createQueries, + "create table t11 (id int primary key, i int, constraint f1201 foreign key (i) references t12 (i) on delete set null);", + "create table t12 (id int primary key, i int, key (i), constraint f1101 foreign key (i) references t11 (id) on delete restrict);", + ), + expectDiffs: 2, + expectDeps: 2, + entityOrder: []string{"t11", "t12"}, + sequential: true, + instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyCreateTableFirst, + }, + { + name: "two table cycle with create, changed lexicographic order, create table first", + fromQueries: append(createQueries, + "create table t11 (id int primary key, i int, key (i));", + ), + toQueries: append( + createQueries, + "create table t12 (id int primary key, i int, constraint f1201 foreign key (i) references t11 (i) on delete set null);", + "create table t11 (id int primary key, i int, key (i), constraint f1101 foreign key (i) references t12 (id) on delete restrict);", + ), + expectDiffs: 2, + expectDeps: 2, + entityOrder: []string{"t12", "t11"}, + sequential: true, + instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyCreateTableFirst, + }, { name: "add FK", toQueries: []string{ @@ -980,7 +1117,41 @@ func TestSchemaDiff(t *testing.T) { instantCapability: InstantDDLCapabilityImpossible, }, { - name: "add and drop FK, add and drop respective tables", + name: "add and drop FK, add and drop column, impossible order even with create table first strategy", + fromQueries: []string{ + "create table t1 (id int primary key, p int, key p_idx (p));", + "create table t2 (id int primary key, p int, key p_idx (p), foreign key (p) references t1 (p) on delete no action);", + }, + toQueries: []string{ + "create table t1 (id int primary key, q int, key q_idx (q));", + "create table t2 (id int primary key, q int, key q_idx (q), foreign key (q) references t1 (q) on delete no action);", + }, + expectDiffs: 2, + expectDeps: 1, + sequential: true, + conflictingDiffs: 2, + instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyCreateTableFirst, + }, + { + name: "add and drop FK, add and drop column, impossible order even with ignore strategy", + fromQueries: []string{ + "create table t1 (id int primary key, p int, key p_idx (p));", + "create table t2 (id int primary key, p int, key p_idx (p), foreign key (p) references t1 (p) on delete no action);", + }, + toQueries: []string{ + "create table t1 (id int primary key, q int, key q_idx (q));", + "create table t2 (id int primary key, q int, key q_idx (q), foreign key (q) references t1 (q) on delete no action);", + }, + expectDiffs: 2, + expectDeps: 1, + sequential: true, + conflictingDiffs: 2, + instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyIgnore, + }, + { + name: "add and drop FK, add and drop respective tables, fk strict", fromQueries: []string{ "create table t1 (id int primary key, p int, key p_idx (p));", "create table t2 (id int primary key, p int, key p_idx (p), foreign key (p) references t1 (p) on delete no action);", @@ -994,6 +1165,41 @@ func TestSchemaDiff(t *testing.T) { sequential: true, entityOrder: []string{"t3", "t2", "t1"}, instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyStrict, + }, + { + name: "add and drop FK, add and drop respective tables, fk create table first", + fromQueries: []string{ + "create table t1 (id int primary key, p int, key p_idx (p));", + "create table t2 (id int primary key, p int, key p_idx (p), foreign key (p) references t1 (p) on delete no action);", + }, + toQueries: []string{ + "create table t2 (id int primary key, p int, key p_idx (p), foreign key (p) references t3 (p) on delete no action);", + "create table t3 (id int primary key, p int, key p_idx (p));", + }, + expectDiffs: 3, + expectDeps: 2, // [alter t2]/[drop t1], [alter t2]/[create t3] + sequential: true, + entityOrder: []string{"t3", "t2", "t1"}, + instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyCreateTableFirst, + }, + { + name: "add and drop FK, add and drop respective tables, fk ignore", + fromQueries: []string{ + "create table t1 (id int primary key, p int, key p_idx (p));", + "create table t2 (id int primary key, p int, key p_idx (p), foreign key (p) references t1 (p) on delete no action);", + }, + toQueries: []string{ + "create table t2 (id int primary key, p int, key p_idx (p), foreign key (p) references t3 (p) on delete no action);", + "create table t3 (id int primary key, p int, key p_idx (p));", + }, + expectDiffs: 3, + expectDeps: 2, // [alter t2]/[drop t1], [alter t2]/[create t3] + sequential: true, + entityOrder: []string{"t3", "t2", "t1"}, + instantCapability: InstantDDLCapabilityImpossible, + fkStrategy: ForeignKeyCheckStrategyIgnore, }, { name: "two identical foreign keys in table, drop one", @@ -1111,7 +1317,7 @@ func TestSchemaDiff(t *testing.T) { require.NoError(t, err) } instantCapability := schemaDiff.InstantDDLCapability() - assert.Equal(t, tc.instantCapability, instantCapability) + assert.Equal(t, tc.instantCapability, instantCapability, "for instant capability") }) } diff --git a/go/vt/schemadiff/types.go b/go/vt/schemadiff/types.go index 2049387140c..cb6bc09df85 100644 --- a/go/vt/schemadiff/types.go +++ b/go/vt/schemadiff/types.go @@ -132,6 +132,7 @@ const ( const ( ForeignKeyCheckStrategyStrict int = iota + ForeignKeyCheckStrategyCreateTableFirst ForeignKeyCheckStrategyIgnore ) From 2531cd035fb8cb0e48489137e24ebedb283cd045 Mon Sep 17 00:00:00 2001 From: Arthur Schreiber Date: Mon, 10 Jun 2024 23:53:04 +0200 Subject: [PATCH 15/40] Do not load table stats when booting `vttablet`. (#15715) Signed-off-by: Arthur Schreiber --- go/mysql/flavor_mysql.go | 11 +- go/mysql/schema.go | 15 +- go/vt/vtexplain/vtexplain_vttablet.go | 17 +- .../tabletserver/health_streamer_test.go | 28 +++ .../tabletserver/query_engine_test.go | 25 ++- .../tabletserver/query_executor_test.go | 21 +- go/vt/vttablet/tabletserver/schema/engine.go | 2 +- .../tabletserver/schema/engine_test.go | 201 +++++++++++------- .../vttablet/tabletserver/schema/main_test.go | 3 +- .../tabletserver/tabletserver_test.go | 16 +- 10 files changed, 232 insertions(+), 107 deletions(-) diff --git a/go/mysql/flavor_mysql.go b/go/mysql/flavor_mysql.go index a1245257c74..5de3dc4ed46 100644 --- a/go/mysql/flavor_mysql.go +++ b/go/mysql/flavor_mysql.go @@ -400,9 +400,18 @@ func (mysqlFlavor) readBinlogEvent(c *Conn) (BinlogEvent, error) { // baseShowTables is part of the Flavor interface. func (mysqlFlavor) baseShowTables() string { - return "SELECT table_name, table_type, unix_timestamp(create_time), table_comment FROM information_schema.tables WHERE table_schema = database()" + return BaseShowTables } +const BaseShowTables = `SELECT t.table_name, + t.table_type, + UNIX_TIMESTAMP(t.create_time), + t.table_comment + FROM information_schema.tables t + WHERE + t.table_schema = database() +` + // TablesWithSize80 is a query to select table along with size for mysql 8.0 // // Note the following: diff --git a/go/mysql/schema.go b/go/mysql/schema.go index d0b9bfe2e79..03d558d2637 100644 --- a/go/mysql/schema.go +++ b/go/mysql/schema.go @@ -78,19 +78,21 @@ var BaseShowTablesFields = []*querypb.Field{{ ColumnLength: 6144, Charset: uint32(collations.SystemCollation.Collation), Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG), -}, { +}} + +var BaseShowTablesWithSizesFields = append(BaseShowTablesFields, &querypb.Field{ Name: "i.file_size", Type: querypb.Type_INT64, ColumnLength: 11, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_BINARY_FLAG | querypb.MySqlFlag_NUM_FLAG), -}, { +}, &querypb.Field{ Name: "i.allocated_size", Type: querypb.Type_INT64, ColumnLength: 11, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_BINARY_FLAG | querypb.MySqlFlag_NUM_FLAG), -}} +}) // BaseShowTablesRow returns the fields from a BaseShowTables or // BaseShowTablesForTable command. @@ -104,9 +106,14 @@ func BaseShowTablesRow(tableName string, isView bool, comment string) []sqltypes sqltypes.MakeTrusted(sqltypes.VarChar, []byte(tableType)), sqltypes.MakeTrusted(sqltypes.Int64, []byte("1427325875")), // unix_timestamp(create_time) sqltypes.MakeTrusted(sqltypes.VarChar, []byte(comment)), + } +} + +func BaseShowTablesWithSizesRow(tableName string, isView bool, comment string) []sqltypes.Value { + return append(BaseShowTablesRow(tableName, isView, comment), sqltypes.MakeTrusted(sqltypes.Int64, []byte("100")), // file_size sqltypes.MakeTrusted(sqltypes.Int64, []byte("150")), // allocated_size - } + ) } // ShowPrimaryFields contains the fields for a BaseShowPrimary. diff --git a/go/vt/vtexplain/vtexplain_vttablet.go b/go/vt/vtexplain/vtexplain_vttablet.go index 6f28cd99ec0..28e7431ad82 100644 --- a/go/vt/vtexplain/vtexplain_vttablet.go +++ b/go/vt/vtexplain/vtexplain_vttablet.go @@ -429,7 +429,9 @@ func newTabletEnvironment(ddls []sqlparser.DDLStatement, opts *Options, collatio tEnv.addResult(query, result) } - showTableRows := make([][]sqltypes.Value, 0, 4) + showTableRows := make([][]sqltypes.Value, 0, len(ddls)) + showTableWithSizesRows := make([][]sqltypes.Value, 0, len(ddls)) + for _, ddl := range ddls { table := ddl.GetTable().Name.String() options := "" @@ -442,14 +444,21 @@ func newTabletEnvironment(ddls []sqlparser.DDLStatement, opts *Options, collatio } } showTableRows = append(showTableRows, mysql.BaseShowTablesRow(table, false, options)) + showTableWithSizesRows = append(showTableWithSizesRows, mysql.BaseShowTablesWithSizesRow(table, true, options)) } - tEnv.addResult(mysql.TablesWithSize57, &sqltypes.Result{ + + tEnv.addResult(mysql.BaseShowTables, &sqltypes.Result{ Fields: mysql.BaseShowTablesFields, Rows: showTableRows, }) + + tEnv.addResult(mysql.TablesWithSize57, &sqltypes.Result{ + Fields: mysql.BaseShowTablesWithSizesFields, + Rows: showTableWithSizesRows, + }) tEnv.addResult(mysql.TablesWithSize80, &sqltypes.Result{ - Fields: mysql.BaseShowTablesFields, - Rows: showTableRows, + Fields: mysql.BaseShowTablesWithSizesFields, + Rows: showTableWithSizesRows, }) indexRows := make([][]sqltypes.Value, 0, 4) diff --git a/go/vt/vttablet/tabletserver/health_streamer_test.go b/go/vt/vttablet/tabletserver/health_streamer_test.go index ff61787dd1d..a97f64c77c6 100644 --- a/go/vt/vttablet/tabletserver/health_streamer_test.go +++ b/go/vt/vttablet/tabletserver/health_streamer_test.go @@ -249,6 +249,17 @@ func TestReloadSchema(t *testing.T) { "product|BASE TABLE|1684735966||114688|114688", "users|BASE TABLE|1684735966||114688|114688", )) + + db.AddQuery(mysql.BaseShowTables, + sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "TABLE_NAME | TABLE_TYPE | UNIX_TIMESTAMP(t.create_time) | TABLE_COMMENT", + "varchar|varchar|int64|varchar", + ), + "product|BASE TABLE|1684735966|", + "users|BASE TABLE|1684735966|", + )) + db.AddQueryPattern("SELECT COLUMN_NAME as column_name.*", sqltypes.MakeTestResult( sqltypes.MakeTestFields( "column_name", @@ -293,6 +304,16 @@ func TestReloadSchema(t *testing.T) { "users|BASE TABLE|1684735967||114688|114688", )) + db.AddQuery(mysql.BaseShowTables, + sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "TABLE_NAME | TABLE_TYPE | UNIX_TIMESTAMP(t.create_time) | TABLE_COMMENT", + "varchar|varchar|int64|varchar", + ), + "product|BASE TABLE|1684735967|", + "users|BASE TABLE|1684735967|", + )) + var wg sync.WaitGroup wg.Add(1) go func() { @@ -359,6 +380,13 @@ func TestReloadView(t *testing.T) { "varchar|varchar|int64|varchar|int64|int64", ), )) + db.AddQuery(mysql.BaseShowTables, + sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "TABLE_NAME | TABLE_TYPE | UNIX_TIMESTAMP(t.create_time) | TABLE_COMMENT", + "varchar|varchar|int64|varchar", + ), + )) db.AddQueryPattern("SELECT COLUMN_NAME as column_name.*", sqltypes.MakeTestResult( sqltypes.MakeTestFields( "column_name", diff --git a/go/vt/vttablet/tabletserver/query_engine_test.go b/go/vt/vttablet/tabletserver/query_engine_test.go index 0de78b8752d..199dc0cf334 100644 --- a/go/vt/vttablet/tabletserver/query_engine_test.go +++ b/go/vt/vttablet/tabletserver/query_engine_test.go @@ -114,15 +114,26 @@ func TestGetPlanPanicDuetoEmptyQuery(t *testing.T) { } func addSchemaEngineQueries(db *fakesqldb.DB) { - db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ - Fields: mysql.BaseShowTablesFields, + db.AddQueryPattern(baseShowTablesWithSizesPattern, &sqltypes.Result{ + Fields: mysql.BaseShowTablesWithSizesFields, Rows: [][]sqltypes.Value{ - mysql.BaseShowTablesRow("test_table_01", false, ""), - mysql.BaseShowTablesRow("test_table_02", false, ""), - mysql.BaseShowTablesRow("test_table_03", false, ""), - mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), - mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), + mysql.BaseShowTablesWithSizesRow("test_table_01", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_02", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_03", false, ""), + mysql.BaseShowTablesWithSizesRow("seq", false, "vitess_sequence"), + mysql.BaseShowTablesWithSizesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), }}) + db.AddQuery(mysql.BaseShowTables, + &sqltypes.Result{ + Fields: mysql.BaseShowTablesFields, + Rows: [][]sqltypes.Value{ + mysql.BaseShowTablesRow("test_table_01", false, ""), + mysql.BaseShowTablesRow("test_table_02", false, ""), + mysql.BaseShowTablesRow("test_table_03", false, ""), + mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), + mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), + }, + }) db.AddQuery("show status like 'Innodb_rows_read'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( "Variable_name|Value", "varchar|int64"), diff --git a/go/vt/vttablet/tabletserver/query_executor_test.go b/go/vt/vttablet/tabletserver/query_executor_test.go index 0c845d7c2ae..c4f3ed1b00c 100644 --- a/go/vt/vttablet/tabletserver/query_executor_test.go +++ b/go/vt/vttablet/tabletserver/query_executor_test.go @@ -1591,18 +1591,27 @@ func setUpQueryExecutorTest(t *testing.T) *fakesqldb.DB { return db } -const baseShowTablesPattern = `SELECT t\.table_name.*` +const baseShowTablesWithSizesPattern = `SELECT t\.table_name.*SUM\(i\.file_size\).*` func initQueryExecutorTestDB(db *fakesqldb.DB) { addQueryExecutorSupportedQueries(db) - db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ - Fields: mysql.BaseShowTablesFields, + db.AddQueryPattern(baseShowTablesWithSizesPattern, &sqltypes.Result{ + Fields: mysql.BaseShowTablesWithSizesFields, Rows: [][]sqltypes.Value{ - mysql.BaseShowTablesRow("test_table", false, ""), - mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), - mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), + mysql.BaseShowTablesWithSizesRow("test_table", false, ""), + mysql.BaseShowTablesWithSizesRow("seq", false, "vitess_sequence"), + mysql.BaseShowTablesWithSizesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), }, }) + db.AddQuery(mysql.BaseShowTables, + &sqltypes.Result{ + Fields: mysql.BaseShowTablesFields, + Rows: [][]sqltypes.Value{ + mysql.BaseShowTablesRow("test_table", false, ""), + mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), + mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), + }, + }) db.AddQuery("show status like 'Innodb_rows_read'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( "Variable_name|Value", "varchar|int64"), diff --git a/go/vt/vttablet/tabletserver/schema/engine.go b/go/vt/vttablet/tabletserver/schema/engine.go index ddc1b376628..da3d1e999e1 100644 --- a/go/vt/vttablet/tabletserver/schema/engine.go +++ b/go/vt/vttablet/tabletserver/schema/engine.go @@ -256,7 +256,7 @@ func (se *Engine) Open() error { } se.notifiers = make(map[string]notifier) - if err := se.reload(ctx, true); err != nil { + if err := se.reload(ctx, false); err != nil { return err } if !se.SkipMetaCheck { diff --git a/go/vt/vttablet/tabletserver/schema/engine_test.go b/go/vt/vttablet/tabletserver/schema/engine_test.go index b3a8b1e2971..d4271dee876 100644 --- a/go/vt/vttablet/tabletserver/schema/engine_test.go +++ b/go/vt/vttablet/tabletserver/schema/engine_test.go @@ -52,7 +52,7 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" ) -const baseShowTablesPattern = `SELECT t\.table_name.*` +const baseShowTablesWithSizesPattern = `SELECT t\.table_name.*SUM\(i\.file_size\).*` var mustMatch = utils.MustMatchFn(".Mutex") @@ -60,21 +60,23 @@ func TestOpenAndReload(t *testing.T) { db := fakesqldb.New(t) defer db.Close() schematest.AddDefaultQueries(db) - db.AddQueryPattern(baseShowTablesPattern, - &sqltypes.Result{ - Fields: mysql.BaseShowTablesFields, - RowsAffected: 0, - InsertID: 0, - Rows: [][]sqltypes.Value{ - mysql.BaseShowTablesRow("test_table_01", false, ""), - mysql.BaseShowTablesRow("test_table_02", false, ""), - mysql.BaseShowTablesRow("test_table_03", false, ""), - mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), - mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), - }, - SessionStateChanges: "", - StatusFlags: 0, - }) + + db.RejectQueryPattern(baseShowTablesWithSizesPattern, "Opening schema engine should query tables without size information") + + db.AddQuery(mysql.BaseShowTables, &sqltypes.Result{ + Fields: mysql.BaseShowTablesFields, + RowsAffected: 0, + InsertID: 0, + Rows: [][]sqltypes.Value{ + mysql.BaseShowTablesRow("test_table_01", false, ""), + mysql.BaseShowTablesRow("test_table_02", false, ""), + mysql.BaseShowTablesRow("test_table_03", false, ""), + mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), + mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), + }, + SessionStateChanges: "", + StatusFlags: 0, + }) // advance to one second after the default 1427325875. db.AddQuery("select unix_timestamp()", sqltypes.MakeTestResult(sqltypes.MakeTestFields( @@ -90,8 +92,8 @@ func TestOpenAndReload(t *testing.T) { want := initialSchema() mustMatch(t, want, se.GetSchema()) - assert.Equal(t, int64(100), se.tableFileSizeGauge.Counts()["msg"]) - assert.Equal(t, int64(150), se.tableAllocatedSizeGauge.Counts()["msg"]) + assert.Equal(t, int64(0), se.tableFileSizeGauge.Counts()["msg"]) + assert.Equal(t, int64(0), se.tableAllocatedSizeGauge.Counts()["msg"]) // Advance time some more. db.AddQuery("select unix_timestamp()", sqltypes.MakeTestResult(sqltypes.MakeTestFields( @@ -104,11 +106,11 @@ func TestOpenAndReload(t *testing.T) { // Modify test_table_03 // Add test_table_04 // Drop msg - db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ - Fields: mysql.BaseShowTablesFields, + db.AddQueryPattern(baseShowTablesWithSizesPattern, &sqltypes.Result{ + Fields: mysql.BaseShowTablesWithSizesFields, Rows: [][]sqltypes.Value{ - mysql.BaseShowTablesRow("test_table_01", false, ""), - mysql.BaseShowTablesRow("test_table_02", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_01", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_02", false, ""), { sqltypes.MakeTrusted(sqltypes.VarChar, []byte("test_table_03")), // table_name sqltypes.MakeTrusted(sqltypes.VarChar, []byte("BASE TABLE")), // table_type @@ -118,10 +120,13 @@ func TestOpenAndReload(t *testing.T) { sqltypes.MakeTrusted(sqltypes.Int64, []byte("256")), // allocated_size }, // test_table_04 will in spite of older timestamp because it doesn't exist yet. - mysql.BaseShowTablesRow("test_table_04", false, ""), - mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), + mysql.BaseShowTablesWithSizesRow("test_table_04", false, ""), + mysql.BaseShowTablesWithSizesRow("seq", false, "vitess_sequence"), }, }) + + db.AddRejectedQuery(mysql.BaseShowTables, fmt.Errorf("Reloading schema engine should query tables with size information")) + db.MockQueriesForTable("test_table_03", &sqltypes.Result{ Fields: []*querypb.Field{{ Name: "pk1", @@ -177,6 +182,15 @@ func TestOpenAndReload(t *testing.T) { assert.EqualValues(t, secondReadRowsValue, se.innoDbReadRowsCounter.Get()) + want["seq"].FileSize = 100 + want["seq"].AllocatedSize = 150 + + want["test_table_01"].FileSize = 100 + want["test_table_01"].AllocatedSize = 150 + + want["test_table_02"].FileSize = 100 + want["test_table_02"].AllocatedSize = 150 + want["test_table_03"] = &Table{ Name: sqlparser.NewIdentifierCS("test_table_03"), Fields: []*querypb.Field{{ @@ -225,7 +239,17 @@ func TestOpenAndReload(t *testing.T) { require.NoError(t, err) assert.Equal(t, want, se.GetSchema()) - db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ + db.AddQueryPattern(baseShowTablesWithSizesPattern, &sqltypes.Result{ + Fields: mysql.BaseShowTablesWithSizesFields, + Rows: [][]sqltypes.Value{ + mysql.BaseShowTablesWithSizesRow("test_table_01", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_02", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_04", false, ""), + mysql.BaseShowTablesWithSizesRow("seq", false, "vitess_sequence"), + }, + }) + + db.AddQuery(mysql.BaseShowTables, &sqltypes.Result{ Fields: mysql.BaseShowTablesFields, Rows: [][]sqltypes.Value{ mysql.BaseShowTablesRow("test_table_01", false, ""), @@ -234,6 +258,7 @@ func TestOpenAndReload(t *testing.T) { mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), }, }) + db.AddQuery(mysql.BaseShowPrimary, &sqltypes.Result{ Fields: mysql.ShowPrimaryFields, Rows: [][]sqltypes.Value{ @@ -257,21 +282,23 @@ func TestReloadWithSwappedTables(t *testing.T) { db := fakesqldb.New(t) defer db.Close() schematest.AddDefaultQueries(db) - db.AddQueryPattern(baseShowTablesPattern, - &sqltypes.Result{ - Fields: mysql.BaseShowTablesFields, - RowsAffected: 0, - InsertID: 0, - Rows: [][]sqltypes.Value{ - mysql.BaseShowTablesRow("test_table_01", false, ""), - mysql.BaseShowTablesRow("test_table_02", false, ""), - mysql.BaseShowTablesRow("test_table_03", false, ""), - mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), - mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), - }, - SessionStateChanges: "", - StatusFlags: 0, - }) + + db.RejectQueryPattern(baseShowTablesWithSizesPattern, "Opening schema engine should query tables without size information") + + db.AddQuery(mysql.BaseShowTables, &sqltypes.Result{ + Fields: mysql.BaseShowTablesFields, + RowsAffected: 0, + InsertID: 0, + Rows: [][]sqltypes.Value{ + mysql.BaseShowTablesWithSizesRow("test_table_01", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_02", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_03", false, ""), + mysql.BaseShowTablesWithSizesRow("seq", false, "vitess_sequence"), + mysql.BaseShowTablesWithSizesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), + }, + SessionStateChanges: "", + StatusFlags: 0, + }) firstReadRowsValue := 12 AddFakeInnoDBReadRowsResult(db, firstReadRowsValue) @@ -288,12 +315,12 @@ func TestReloadWithSwappedTables(t *testing.T) { "int64"), "1427325876", )) - db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ - Fields: mysql.BaseShowTablesFields, + db.AddQueryPattern(baseShowTablesWithSizesPattern, &sqltypes.Result{ + Fields: mysql.BaseShowTablesWithSizesFields, Rows: [][]sqltypes.Value{ - mysql.BaseShowTablesRow("test_table_01", false, ""), - mysql.BaseShowTablesRow("test_table_02", false, ""), - mysql.BaseShowTablesRow("test_table_03", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_01", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_02", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_03", false, ""), { sqltypes.MakeTrusted(sqltypes.VarChar, []byte("test_table_04")), sqltypes.MakeTrusted(sqltypes.VarChar, []byte("BASE TABLE")), @@ -302,8 +329,8 @@ func TestReloadWithSwappedTables(t *testing.T) { sqltypes.MakeTrusted(sqltypes.Int64, []byte("128")), // file_size sqltypes.MakeTrusted(sqltypes.Int64, []byte("256")), // allocated_size }, - mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), - mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), + mysql.BaseShowTablesWithSizesRow("seq", false, "vitess_sequence"), + mysql.BaseShowTablesWithSizesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), }, }) db.MockQueriesForTable("test_table_04", &sqltypes.Result{ @@ -325,6 +352,22 @@ func TestReloadWithSwappedTables(t *testing.T) { }) err := se.Reload(context.Background()) require.NoError(t, err) + + want["msg"].FileSize = 100 + want["msg"].AllocatedSize = 150 + + want["seq"].FileSize = 100 + want["seq"].AllocatedSize = 150 + + want["test_table_01"].FileSize = 100 + want["test_table_01"].AllocatedSize = 150 + + want["test_table_02"].FileSize = 100 + want["test_table_02"].AllocatedSize = 150 + + want["test_table_03"].FileSize = 100 + want["test_table_03"].AllocatedSize = 150 + want["test_table_04"] = &Table{ Name: sqlparser.NewIdentifierCS("test_table_04"), Fields: []*querypb.Field{{ @@ -346,11 +389,11 @@ func TestReloadWithSwappedTables(t *testing.T) { "int64"), "1427325877", )) - db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ - Fields: mysql.BaseShowTablesFields, + db.AddQueryPattern(baseShowTablesWithSizesPattern, &sqltypes.Result{ + Fields: mysql.BaseShowTablesWithSizesFields, Rows: [][]sqltypes.Value{ - mysql.BaseShowTablesRow("test_table_01", false, ""), - mysql.BaseShowTablesRow("test_table_02", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_01", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_02", false, ""), { sqltypes.MakeTrusted(sqltypes.VarChar, []byte("test_table_03")), sqltypes.MakeTrusted(sqltypes.VarChar, []byte("BASE TABLE")), @@ -359,9 +402,9 @@ func TestReloadWithSwappedTables(t *testing.T) { sqltypes.MakeTrusted(sqltypes.Int64, []byte("128")), // file_size sqltypes.MakeTrusted(sqltypes.Int64, []byte("256")), // allocated_size }, - mysql.BaseShowTablesRow("test_table_04", false, ""), - mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), - mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), + mysql.BaseShowTablesWithSizesRow("test_table_04", false, ""), + mysql.BaseShowTablesWithSizesRow("seq", false, "vitess_sequence"), + mysql.BaseShowTablesWithSizesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), }, }) db.MockQueriesForTable("test_table_03", &sqltypes.Result{ @@ -424,7 +467,7 @@ func TestOpenFailedDueToExecErr(t *testing.T) { defer db.Close() schematest.AddDefaultQueries(db) want := "injected error" - db.RejectQueryPattern(baseShowTablesPattern, want) + db.AddRejectedQuery(mysql.BaseShowTables, fmt.Errorf(want)) se := newEngine(1*time.Second, 1*time.Second, 0, db) err := se.Open() if err == nil || !strings.Contains(err.Error(), want) { @@ -439,11 +482,11 @@ func TestOpenFailedDueToLoadTableErr(t *testing.T) { db := fakesqldb.New(t) defer db.Close() schematest.AddDefaultQueries(db) - db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ + db.AddQuery(mysql.BaseShowTables, &sqltypes.Result{ Fields: mysql.BaseShowTablesFields, Rows: [][]sqltypes.Value{ - mysql.BaseShowTablesRow("test_table", false, ""), - mysql.BaseShowTablesRow("test_view", true, "VIEW"), + mysql.BaseShowTablesWithSizesRow("test_table", false, ""), + mysql.BaseShowTablesWithSizesRow("test_view", true, "VIEW"), }, }) // this will cause NewTable error, as it expects zero rows. @@ -474,11 +517,11 @@ func TestOpenNoErrorDueToInvalidViews(t *testing.T) { db := fakesqldb.New(t) defer db.Close() schematest.AddDefaultQueries(db) - db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ + db.AddQuery(mysql.BaseShowTables, &sqltypes.Result{ Fields: mysql.BaseShowTablesFields, Rows: [][]sqltypes.Value{ - mysql.BaseShowTablesRow("foo_view", true, "VIEW"), - mysql.BaseShowTablesRow("bar_view", true, "VIEW"), + mysql.BaseShowTablesWithSizesRow("foo_view", true, "VIEW"), + mysql.BaseShowTablesWithSizesRow("bar_view", true, "VIEW"), }, }) @@ -532,17 +575,17 @@ func TestSchemaEngineCloseTickRace(t *testing.T) { db := fakesqldb.New(t) defer db.Close() schematest.AddDefaultQueries(db) - db.AddQueryPattern(baseShowTablesPattern, + db.AddQuery(mysql.BaseShowTables, &sqltypes.Result{ Fields: mysql.BaseShowTablesFields, RowsAffected: 0, InsertID: 0, Rows: [][]sqltypes.Value{ - mysql.BaseShowTablesRow("test_table_01", false, ""), - mysql.BaseShowTablesRow("test_table_02", false, ""), - mysql.BaseShowTablesRow("test_table_03", false, ""), - mysql.BaseShowTablesRow("seq", false, "vitess_sequence"), - mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), + mysql.BaseShowTablesWithSizesRow("test_table_01", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_02", false, ""), + mysql.BaseShowTablesWithSizesRow("test_table_03", false, ""), + mysql.BaseShowTablesWithSizesRow("seq", false, "vitess_sequence"), + mysql.BaseShowTablesWithSizesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), }, SessionStateChanges: "", StatusFlags: 0, @@ -607,8 +650,8 @@ func initialSchema() map[string]*Table { }}, PKColumns: []int{0}, CreateTime: 1427325875, - FileSize: 0x64, - AllocatedSize: 0x96, + FileSize: 0, + AllocatedSize: 0, }, "test_table_02": { Name: sqlparser.NewIdentifierCS("test_table_02"), @@ -618,8 +661,8 @@ func initialSchema() map[string]*Table { }}, PKColumns: []int{0}, CreateTime: 1427325875, - FileSize: 0x64, - AllocatedSize: 0x96, + FileSize: 0, + AllocatedSize: 0, }, "test_table_03": { Name: sqlparser.NewIdentifierCS("test_table_03"), @@ -629,8 +672,8 @@ func initialSchema() map[string]*Table { }}, PKColumns: []int{0}, CreateTime: 1427325875, - FileSize: 0x64, - AllocatedSize: 0x96, + FileSize: 0, + AllocatedSize: 0, }, "seq": { Name: sqlparser.NewIdentifierCS("seq"), @@ -650,8 +693,8 @@ func initialSchema() map[string]*Table { }}, PKColumns: []int{0}, CreateTime: 1427325875, - FileSize: 0x64, - AllocatedSize: 0x96, + FileSize: 0, + AllocatedSize: 0, SequenceInfo: &SequenceInfo{}, }, "msg": { @@ -678,8 +721,8 @@ func initialSchema() map[string]*Table { }}, PKColumns: []int{0}, CreateTime: 1427325875, - FileSize: 0x64, - AllocatedSize: 0x96, + FileSize: 0, + AllocatedSize: 0, MessageInfo: &MessageInfo{ Fields: []*querypb.Field{{ Name: "id", @@ -1346,9 +1389,9 @@ func TestGetTableForPos(t *testing.T) { db.AddQuery(fmt.Sprintf(readTableCreateTimes, sidecar.GetIdentifier()), sqltypes.MakeTestResult(sqltypes.MakeTestFields("table_name|create_time", "varchar|int64"))) db.AddQuery(fmt.Sprintf(detectUdfChange, sidecar.GetIdentifier()), &sqltypes.Result{}) - db.AddQueryPattern(baseShowTablesPattern, + db.AddQueryPattern(baseShowTablesWithSizesPattern, &sqltypes.Result{ - Fields: mysql.BaseShowTablesFields, + Fields: mysql.BaseShowTablesWithSizesFields, RowsAffected: 0, InsertID: 0, Rows: [][]sqltypes.Value{ diff --git a/go/vt/vttablet/tabletserver/schema/main_test.go b/go/vt/vttablet/tabletserver/schema/main_test.go index 0948c1313fc..7eaca5f18e5 100644 --- a/go/vt/vttablet/tabletserver/schema/main_test.go +++ b/go/vt/vttablet/tabletserver/schema/main_test.go @@ -34,7 +34,8 @@ func getTestSchemaEngine(t *testing.T, schemaMaxAgeSeconds int64) (*Engine, *fak "int64"), "1427325876", )) - db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{}) + db.AddQueryPattern(baseShowTablesWithSizesPattern, &sqltypes.Result{}) + db.AddQuery(mysql.BaseShowTables, &sqltypes.Result{}) db.AddQuery(mysql.BaseShowPrimary, &sqltypes.Result{}) AddFakeInnoDBReadRowsResult(db, 1) se := newEngine(10*time.Second, 10*time.Second, schemaMaxAgeSeconds, db) diff --git a/go/vt/vttablet/tabletserver/tabletserver_test.go b/go/vt/vttablet/tabletserver/tabletserver_test.go index 92bfa25650a..ee91f05c2a5 100644 --- a/go/vt/vttablet/tabletserver/tabletserver_test.go +++ b/go/vt/vttablet/tabletserver/tabletserver_test.go @@ -2619,13 +2619,21 @@ func setupTabletServerTestCustom(t testing.TB, ctx context.Context, cfg *tablete func setupFakeDB(t testing.TB) *fakesqldb.DB { db := fakesqldb.New(t) addTabletServerSupportedQueries(db) - db.AddQueryPattern(baseShowTablesPattern, &sqltypes.Result{ - Fields: mysql.BaseShowTablesFields, + db.AddQueryPattern(baseShowTablesWithSizesPattern, &sqltypes.Result{ + Fields: mysql.BaseShowTablesWithSizesFields, Rows: [][]sqltypes.Value{ - mysql.BaseShowTablesRow("test_table", false, ""), - mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), + mysql.BaseShowTablesWithSizesRow("test_table", false, ""), + mysql.BaseShowTablesWithSizesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), }, }) + db.AddQuery(mysql.BaseShowTables, + &sqltypes.Result{ + Fields: mysql.BaseShowTablesFields, + Rows: [][]sqltypes.Value{ + mysql.BaseShowTablesRow("test_table", false, ""), + mysql.BaseShowTablesRow("msg", false, "vitess_message,vt_ack_wait=30,vt_purge_after=120,vt_batch_size=1,vt_cache_size=10,vt_poller_interval=30"), + }, + }) db.AddQuery("show status like 'Innodb_rows_read'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( "Variable_name|Value", "varchar|int64"), From dbb8863bc9655bd7504e6c441786ff72c6755f6d Mon Sep 17 00:00:00 2001 From: Arthur Schreiber Date: Tue, 11 Jun 2024 07:37:25 +0200 Subject: [PATCH 16/40] Add parsing support for `ANY`/`SOME`/`ALL` comparison modifiers. (#16080) Signed-off-by: Arthur Schreiber Signed-off-by: Andres Taylor Signed-off-by: Manan Gupta Co-authored-by: Andres Taylor Co-authored-by: Manan Gupta --- go/vt/sqlparser/ast.go | 4 + go/vt/sqlparser/ast_equals.go | 1 + go/vt/sqlparser/ast_format.go | 8 +- go/vt/sqlparser/ast_format_fast.go | 5 + go/vt/sqlparser/constants.go | 6 + go/vt/sqlparser/keywords.go | 2 + go/vt/sqlparser/parse_test.go | 13 +- go/vt/sqlparser/sql.go | 19662 ++++++++-------- go/vt/sqlparser/sql.y | 39 +- go/vt/sqlparser/testdata/select_cases.txt | 4 +- .../planbuilder/testdata/select_cases.json | 46 + .../testdata/unsupported_cases.json | 15 + go/vt/vtgate/semantics/analyzer.go | 22 +- go/vt/vtgate/semantics/binder.go | 2 +- go/vt/vtgate/semantics/check_invalid.go | 4 + 15 files changed, 10009 insertions(+), 9824 deletions(-) diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index 0026764970e..4e96a3ea372 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -2273,6 +2273,7 @@ type ( // ComparisonExpr represents a two-value comparison expression. ComparisonExpr struct { Operator ComparisonExprOperator + Modifier ComparisonModifier Left, Right Expr Escape Expr } @@ -2280,6 +2281,9 @@ type ( // ComparisonExprOperator is an enum for ComparisonExpr.Operator ComparisonExprOperator int8 + // ComparisonModifier is an enum for ComparisonExpr.Modifier + ComparisonModifier int8 + // BetweenExpr represents a BETWEEN or a NOT BETWEEN expression. BetweenExpr struct { IsBetween bool diff --git a/go/vt/sqlparser/ast_equals.go b/go/vt/sqlparser/ast_equals.go index 386731a47ad..a775cb7f8bf 100644 --- a/go/vt/sqlparser/ast_equals.go +++ b/go/vt/sqlparser/ast_equals.go @@ -2187,6 +2187,7 @@ func (cmp *Comparator) RefOfComparisonExpr(a, b *ComparisonExpr) bool { return false } return a.Operator == b.Operator && + a.Modifier == b.Modifier && cmp.Expr(a.Left, b.Left) && cmp.Expr(a.Right, b.Right) && cmp.Expr(a.Escape, b.Escape) diff --git a/go/vt/sqlparser/ast_format.go b/go/vt/sqlparser/ast_format.go index caba74fb567..8d8a01a6eb2 100644 --- a/go/vt/sqlparser/ast_format.go +++ b/go/vt/sqlparser/ast_format.go @@ -1301,7 +1301,13 @@ func (node *NotExpr) Format(buf *TrackedBuffer) { // Format formats the node. func (node *ComparisonExpr) Format(buf *TrackedBuffer) { - buf.astPrintf(node, "%l %s %r", node.Left, node.Operator.ToString(), node.Right) + buf.astPrintf(node, "%l %s", node.Left, node.Operator.ToString()) + if node.Modifier == All { + buf.literal(" all") + } else if node.Modifier == Any { + buf.literal(" any") + } + buf.astPrintf(node, " %r", node.Right) if node.Escape != nil { buf.astPrintf(node, " escape %v", node.Escape) } diff --git a/go/vt/sqlparser/ast_format_fast.go b/go/vt/sqlparser/ast_format_fast.go index 3858cd56715..4be0bfd75f7 100644 --- a/go/vt/sqlparser/ast_format_fast.go +++ b/go/vt/sqlparser/ast_format_fast.go @@ -1698,6 +1698,11 @@ func (node *ComparisonExpr) FormatFast(buf *TrackedBuffer) { buf.printExpr(node, node.Left, true) buf.WriteByte(' ') buf.WriteString(node.Operator.ToString()) + if node.Modifier == All { + buf.WriteString(" all") + } else if node.Modifier == Any { + buf.WriteString(" any") + } buf.WriteByte(' ') buf.printExpr(node, node.Right, false) if node.Escape != nil { diff --git a/go/vt/sqlparser/constants.go b/go/vt/sqlparser/constants.go index b1f33184ec0..024a2148c33 100644 --- a/go/vt/sqlparser/constants.go +++ b/go/vt/sqlparser/constants.go @@ -677,6 +677,12 @@ const ( NotRegexpOp ) +const ( + Missing ComparisonModifier = iota + Any + All +) + func (op ComparisonExprOperator) Inverse() ComparisonExprOperator { switch op { case EqualOp: diff --git a/go/vt/sqlparser/keywords.go b/go/vt/sqlparser/keywords.go index ef5aa80bff1..2f83d026fbc 100644 --- a/go/vt/sqlparser/keywords.go +++ b/go/vt/sqlparser/keywords.go @@ -126,6 +126,7 @@ var keywords = []keyword{ {"always", ALWAYS}, {"analyze", ANALYZE}, {"and", AND}, + {"any", ANY}, {"any_value", ANY_VALUE}, {"array", ARRAY}, {"as", AS}, @@ -584,6 +585,7 @@ var keywords = []keyword{ {"slow", SLOW}, {"smallint", SMALLINT}, {"snapshot", SNAPSHOT}, + {"some", SOME}, {"spatial", SPATIAL}, {"specific", UNUSED}, {"sql", SQL}, diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index 93f74cfacbc..0fef81f4514 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -3798,7 +3798,15 @@ var ( }, { input: `select * from tbl where foo is unknown or bar is not unknown`, output: `select * from tbl where foo is null or bar is not null`, - }} + }, { + input: `select * from tbl where foo = any (select foo from tbl2)`, + }, { + input: `select * from tbl where foo = some (select foo from tbl2)`, + output: `select * from tbl where foo = any (select foo from tbl2)`, + }, { + input: `select * from tbl where foo > any (select foo from tbl2)`, + }, { + input: `select * from tbl where foo > all (select foo from tbl2)`}} ) func TestValid(t *testing.T) { @@ -4045,6 +4053,9 @@ func TestInvalid(t *testing.T) { }, { input: "SELECT 0b2 FROM user", err: "syntax error at position 11", + }, { + input: "select * from foo where b <=> any (select id from t1)", + err: "syntax error at position 42", }, } diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 2fa91d9fda5..75f5c204ac9 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -39,24 +39,24 @@ const MEMBER = 57346 const MULTIPLE_TEXT_LITERAL = 57347 const FUNCTION_CALL_NON_KEYWORD = 57348 const STRING_TYPE_PREFIX_NON_KEYWORD = 57349 -const LEX_ERROR = 57350 -const UNION = 57351 -const SELECT = 57352 -const STREAM = 57353 -const VSTREAM = 57354 -const INSERT = 57355 -const UPDATE = 57356 -const DELETE = 57357 -const FROM = 57358 -const WHERE = 57359 -const GROUP = 57360 -const HAVING = 57361 -const ORDER = 57362 -const BY = 57363 -const LIMIT = 57364 -const OFFSET = 57365 -const FOR = 57366 -const ALL = 57367 +const ANY_SOME = 57350 +const LEX_ERROR = 57351 +const UNION = 57352 +const SELECT = 57353 +const STREAM = 57354 +const VSTREAM = 57355 +const INSERT = 57356 +const UPDATE = 57357 +const DELETE = 57358 +const FROM = 57359 +const WHERE = 57360 +const GROUP = 57361 +const HAVING = 57362 +const ORDER = 57363 +const BY = 57364 +const LIMIT = 57365 +const OFFSET = 57366 +const FOR = 57367 const DISTINCT = 57368 const AS = 57369 const EXISTS = 57370 @@ -71,686 +71,689 @@ const UNLOCK = 57378 const KEYS = 57379 const DO = 57380 const CALL = 57381 -const DISTINCTROW = 57382 -const PARSER = 57383 -const GENERATED = 57384 -const ALWAYS = 57385 -const OUTFILE = 57386 -const S3 = 57387 -const DATA = 57388 -const LOAD = 57389 -const LINES = 57390 -const TERMINATED = 57391 -const ESCAPED = 57392 -const ENCLOSED = 57393 -const DUMPFILE = 57394 -const CSV = 57395 -const HEADER = 57396 -const MANIFEST = 57397 -const OVERWRITE = 57398 -const STARTING = 57399 -const OPTIONALLY = 57400 -const VALUES = 57401 -const LAST_INSERT_ID = 57402 -const NEXT = 57403 -const VALUE = 57404 -const SHARE = 57405 -const MODE = 57406 -const SQL_NO_CACHE = 57407 -const SQL_CACHE = 57408 -const SQL_CALC_FOUND_ROWS = 57409 -const JOIN = 57410 -const STRAIGHT_JOIN = 57411 -const LEFT = 57412 -const RIGHT = 57413 -const INNER = 57414 -const OUTER = 57415 -const CROSS = 57416 -const NATURAL = 57417 -const USE = 57418 -const FORCE = 57419 -const ON = 57420 -const USING = 57421 -const INPLACE = 57422 -const COPY = 57423 -const INSTANT = 57424 -const ALGORITHM = 57425 -const NONE = 57426 -const SHARED = 57427 -const EXCLUSIVE = 57428 -const SUBQUERY_AS_EXPR = 57429 -const STRING = 57430 -const ID = 57431 -const AT_ID = 57432 -const AT_AT_ID = 57433 -const HEX = 57434 -const NCHAR_STRING = 57435 -const INTEGRAL = 57436 -const FLOAT = 57437 -const DECIMAL = 57438 -const HEXNUM = 57439 -const COMMENT = 57440 -const COMMENT_KEYWORD = 57441 -const BITNUM = 57442 -const BIT_LITERAL = 57443 -const COMPRESSION = 57444 -const VALUE_ARG = 57445 -const LIST_ARG = 57446 -const OFFSET_ARG = 57447 -const JSON_PRETTY = 57448 -const JSON_STORAGE_SIZE = 57449 -const JSON_STORAGE_FREE = 57450 -const JSON_CONTAINS = 57451 -const JSON_CONTAINS_PATH = 57452 -const JSON_EXTRACT = 57453 -const JSON_KEYS = 57454 -const JSON_OVERLAPS = 57455 -const JSON_SEARCH = 57456 -const JSON_VALUE = 57457 -const EXTRACT = 57458 -const NULL = 57459 -const UNKNOWN = 57460 -const TRUE = 57461 -const FALSE = 57462 -const OFF = 57463 -const DISCARD = 57464 -const IMPORT = 57465 -const ENABLE = 57466 -const DISABLE = 57467 -const TABLESPACE = 57468 -const VIRTUAL = 57469 -const STORED = 57470 -const BOTH = 57471 -const LEADING = 57472 -const TRAILING = 57473 -const KILL = 57474 -const EMPTY_FROM_CLAUSE = 57475 -const LOWER_THAN_CHARSET = 57476 -const CHARSET = 57477 -const UNIQUE = 57478 -const KEY = 57479 -const EXPRESSION_PREC_SETTER = 57480 -const OR = 57481 -const XOR = 57482 -const AND = 57483 -const NOT = 57484 -const BETWEEN = 57485 -const CASE = 57486 -const WHEN = 57487 -const THEN = 57488 -const ELSE = 57489 -const END = 57490 -const LE = 57491 -const GE = 57492 -const NE = 57493 -const NULL_SAFE_EQUAL = 57494 -const IS = 57495 -const LIKE = 57496 -const REGEXP = 57497 -const RLIKE = 57498 -const IN = 57499 -const ASSIGNMENT_OPT = 57500 -const SHIFT_LEFT = 57501 -const SHIFT_RIGHT = 57502 -const DIV = 57503 -const MOD = 57504 -const UNARY = 57505 -const COLLATE = 57506 -const BINARY = 57507 -const UNDERSCORE_ARMSCII8 = 57508 -const UNDERSCORE_ASCII = 57509 -const UNDERSCORE_BIG5 = 57510 -const UNDERSCORE_BINARY = 57511 -const UNDERSCORE_CP1250 = 57512 -const UNDERSCORE_CP1251 = 57513 -const UNDERSCORE_CP1256 = 57514 -const UNDERSCORE_CP1257 = 57515 -const UNDERSCORE_CP850 = 57516 -const UNDERSCORE_CP852 = 57517 -const UNDERSCORE_CP866 = 57518 -const UNDERSCORE_CP932 = 57519 -const UNDERSCORE_DEC8 = 57520 -const UNDERSCORE_EUCJPMS = 57521 -const UNDERSCORE_EUCKR = 57522 -const UNDERSCORE_GB18030 = 57523 -const UNDERSCORE_GB2312 = 57524 -const UNDERSCORE_GBK = 57525 -const UNDERSCORE_GEOSTD8 = 57526 -const UNDERSCORE_GREEK = 57527 -const UNDERSCORE_HEBREW = 57528 -const UNDERSCORE_HP8 = 57529 -const UNDERSCORE_KEYBCS2 = 57530 -const UNDERSCORE_KOI8R = 57531 -const UNDERSCORE_KOI8U = 57532 -const UNDERSCORE_LATIN1 = 57533 -const UNDERSCORE_LATIN2 = 57534 -const UNDERSCORE_LATIN5 = 57535 -const UNDERSCORE_LATIN7 = 57536 -const UNDERSCORE_MACCE = 57537 -const UNDERSCORE_MACROMAN = 57538 -const UNDERSCORE_SJIS = 57539 -const UNDERSCORE_SWE7 = 57540 -const UNDERSCORE_TIS620 = 57541 -const UNDERSCORE_UCS2 = 57542 -const UNDERSCORE_UJIS = 57543 -const UNDERSCORE_UTF16 = 57544 -const UNDERSCORE_UTF16LE = 57545 -const UNDERSCORE_UTF32 = 57546 -const UNDERSCORE_UTF8 = 57547 -const UNDERSCORE_UTF8MB4 = 57548 -const UNDERSCORE_UTF8MB3 = 57549 -const INTERVAL = 57550 -const WINDOW_EXPR = 57551 -const JSON_EXTRACT_OP = 57552 -const JSON_UNQUOTE_EXTRACT_OP = 57553 -const CREATE = 57554 -const ALTER = 57555 -const DROP = 57556 -const RENAME = 57557 -const ANALYZE = 57558 -const ADD = 57559 -const FLUSH = 57560 -const CHANGE = 57561 -const MODIFY = 57562 -const DEALLOCATE = 57563 -const REVERT = 57564 -const QUERIES = 57565 -const SCHEMA = 57566 -const TABLE = 57567 -const INDEX = 57568 -const VIEW = 57569 -const TO = 57570 -const IGNORE = 57571 -const IF = 57572 -const PRIMARY = 57573 -const COLUMN = 57574 -const SPATIAL = 57575 -const FULLTEXT = 57576 -const KEY_BLOCK_SIZE = 57577 -const CHECK = 57578 -const INDEXES = 57579 -const ACTION = 57580 -const CASCADE = 57581 -const CONSTRAINT = 57582 -const FOREIGN = 57583 -const NO = 57584 -const REFERENCES = 57585 -const RESTRICT = 57586 -const SHOW = 57587 -const DESCRIBE = 57588 -const EXPLAIN = 57589 -const DATE = 57590 -const ESCAPE = 57591 -const REPAIR = 57592 -const OPTIMIZE = 57593 -const TRUNCATE = 57594 -const COALESCE = 57595 -const EXCHANGE = 57596 -const REBUILD = 57597 -const PARTITIONING = 57598 -const REMOVE = 57599 -const PREPARE = 57600 -const EXECUTE = 57601 -const MAXVALUE = 57602 -const PARTITION = 57603 -const REORGANIZE = 57604 -const LESS = 57605 -const THAN = 57606 -const PROCEDURE = 57607 -const TRIGGER = 57608 -const VINDEX = 57609 -const VINDEXES = 57610 -const DIRECTORY = 57611 -const NAME = 57612 -const UPGRADE = 57613 -const STATUS = 57614 -const VARIABLES = 57615 -const WARNINGS = 57616 -const CASCADED = 57617 -const DEFINER = 57618 -const OPTION = 57619 -const SQL = 57620 -const UNDEFINED = 57621 -const SEQUENCE = 57622 -const MERGE = 57623 -const TEMPORARY = 57624 -const TEMPTABLE = 57625 -const INVOKER = 57626 -const SECURITY = 57627 -const FIRST = 57628 -const AFTER = 57629 -const LAST = 57630 -const VITESS_MIGRATION = 57631 -const CANCEL = 57632 -const RETRY = 57633 -const LAUNCH = 57634 -const COMPLETE = 57635 -const CLEANUP = 57636 -const THROTTLE = 57637 -const UNTHROTTLE = 57638 -const FORCE_CUTOVER = 57639 -const EXPIRE = 57640 -const RATIO = 57641 -const VITESS_THROTTLER = 57642 -const BEGIN = 57643 -const START = 57644 -const TRANSACTION = 57645 -const COMMIT = 57646 -const ROLLBACK = 57647 -const SAVEPOINT = 57648 -const RELEASE = 57649 -const WORK = 57650 -const CONSISTENT = 57651 -const SNAPSHOT = 57652 -const BIT = 57653 -const TINYINT = 57654 -const SMALLINT = 57655 -const MEDIUMINT = 57656 -const INT = 57657 -const INTEGER = 57658 -const BIGINT = 57659 -const INTNUM = 57660 -const REAL = 57661 -const DOUBLE = 57662 -const FLOAT_TYPE = 57663 -const FLOAT4_TYPE = 57664 -const FLOAT8_TYPE = 57665 -const DECIMAL_TYPE = 57666 -const NUMERIC = 57667 -const TIME = 57668 -const TIMESTAMP = 57669 -const DATETIME = 57670 -const YEAR = 57671 -const CHAR = 57672 -const VARCHAR = 57673 -const BOOL = 57674 -const CHARACTER = 57675 -const VARBINARY = 57676 -const NCHAR = 57677 -const TEXT = 57678 -const TINYTEXT = 57679 -const MEDIUMTEXT = 57680 -const LONGTEXT = 57681 -const BLOB = 57682 -const TINYBLOB = 57683 -const MEDIUMBLOB = 57684 -const LONGBLOB = 57685 -const JSON = 57686 -const JSON_SCHEMA_VALID = 57687 -const JSON_SCHEMA_VALIDATION_REPORT = 57688 -const ENUM = 57689 -const GEOMETRY = 57690 -const POINT = 57691 -const LINESTRING = 57692 -const POLYGON = 57693 -const GEOMCOLLECTION = 57694 -const GEOMETRYCOLLECTION = 57695 -const MULTIPOINT = 57696 -const MULTILINESTRING = 57697 -const MULTIPOLYGON = 57698 -const ASCII = 57699 -const UNICODE = 57700 -const NULLX = 57701 -const AUTO_INCREMENT = 57702 -const APPROXNUM = 57703 -const SIGNED = 57704 -const UNSIGNED = 57705 -const ZEROFILL = 57706 -const PURGE = 57707 -const BEFORE = 57708 -const CODE = 57709 -const COLLATION = 57710 -const COLUMNS = 57711 -const DATABASES = 57712 -const ENGINES = 57713 -const EVENT = 57714 -const EXTENDED = 57715 -const FIELDS = 57716 -const FULL = 57717 -const FUNCTION = 57718 -const GTID_EXECUTED = 57719 -const KEYSPACES = 57720 -const OPEN = 57721 -const PLUGINS = 57722 -const PRIVILEGES = 57723 -const PROCESSLIST = 57724 -const SCHEMAS = 57725 -const TABLES = 57726 -const TRIGGERS = 57727 -const USER = 57728 -const VGTID_EXECUTED = 57729 -const VITESS_KEYSPACES = 57730 -const VITESS_METADATA = 57731 -const VITESS_MIGRATIONS = 57732 -const VITESS_REPLICATION_STATUS = 57733 -const VITESS_SHARDS = 57734 -const VITESS_TABLETS = 57735 -const VITESS_TARGET = 57736 -const VSCHEMA = 57737 -const VITESS_THROTTLED_APPS = 57738 -const NAMES = 57739 -const GLOBAL = 57740 -const SESSION = 57741 -const ISOLATION = 57742 -const LEVEL = 57743 -const READ = 57744 -const WRITE = 57745 -const ONLY = 57746 -const REPEATABLE = 57747 -const COMMITTED = 57748 -const UNCOMMITTED = 57749 -const SERIALIZABLE = 57750 -const ADDDATE = 57751 -const CURRENT_TIMESTAMP = 57752 -const DATABASE = 57753 -const CURRENT_DATE = 57754 -const CURDATE = 57755 -const DATE_ADD = 57756 -const DATE_SUB = 57757 -const NOW = 57758 -const SUBDATE = 57759 -const CURTIME = 57760 -const CURRENT_TIME = 57761 -const LOCALTIME = 57762 -const LOCALTIMESTAMP = 57763 -const CURRENT_USER = 57764 -const UTC_DATE = 57765 -const UTC_TIME = 57766 -const UTC_TIMESTAMP = 57767 -const SYSDATE = 57768 -const DAY = 57769 -const DAY_HOUR = 57770 -const DAY_MICROSECOND = 57771 -const DAY_MINUTE = 57772 -const DAY_SECOND = 57773 -const HOUR = 57774 -const HOUR_MICROSECOND = 57775 -const HOUR_MINUTE = 57776 -const HOUR_SECOND = 57777 -const MICROSECOND = 57778 -const MINUTE = 57779 -const MINUTE_MICROSECOND = 57780 -const MINUTE_SECOND = 57781 -const MONTH = 57782 -const QUARTER = 57783 -const SECOND = 57784 -const SECOND_MICROSECOND = 57785 -const YEAR_MONTH = 57786 -const WEEK = 57787 -const SQL_TSI_DAY = 57788 -const SQL_TSI_WEEK = 57789 -const SQL_TSI_HOUR = 57790 -const SQL_TSI_MINUTE = 57791 -const SQL_TSI_MONTH = 57792 -const SQL_TSI_QUARTER = 57793 -const SQL_TSI_SECOND = 57794 -const SQL_TSI_MICROSECOND = 57795 -const SQL_TSI_YEAR = 57796 -const REPLACE = 57797 -const CONVERT = 57798 -const CAST = 57799 -const SUBSTR = 57800 -const SUBSTRING = 57801 -const MID = 57802 -const SEPARATOR = 57803 -const TIMESTAMPADD = 57804 -const TIMESTAMPDIFF = 57805 -const WEIGHT_STRING = 57806 -const LTRIM = 57807 -const RTRIM = 57808 -const TRIM = 57809 -const JSON_ARRAY = 57810 -const JSON_OBJECT = 57811 -const JSON_QUOTE = 57812 -const JSON_DEPTH = 57813 -const JSON_TYPE = 57814 -const JSON_LENGTH = 57815 -const JSON_VALID = 57816 -const JSON_ARRAY_APPEND = 57817 -const JSON_ARRAY_INSERT = 57818 -const JSON_INSERT = 57819 -const JSON_MERGE = 57820 -const JSON_MERGE_PATCH = 57821 -const JSON_MERGE_PRESERVE = 57822 -const JSON_REMOVE = 57823 -const JSON_REPLACE = 57824 -const JSON_SET = 57825 -const JSON_UNQUOTE = 57826 -const COUNT = 57827 -const AVG = 57828 -const MAX = 57829 -const MIN = 57830 -const SUM = 57831 -const GROUP_CONCAT = 57832 -const BIT_AND = 57833 -const BIT_OR = 57834 -const BIT_XOR = 57835 -const STD = 57836 -const STDDEV = 57837 -const STDDEV_POP = 57838 -const STDDEV_SAMP = 57839 -const VAR_POP = 57840 -const VAR_SAMP = 57841 -const VARIANCE = 57842 -const ANY_VALUE = 57843 -const REGEXP_INSTR = 57844 -const REGEXP_LIKE = 57845 -const REGEXP_REPLACE = 57846 -const REGEXP_SUBSTR = 57847 -const ExtractValue = 57848 -const UpdateXML = 57849 -const GET_LOCK = 57850 -const RELEASE_LOCK = 57851 -const RELEASE_ALL_LOCKS = 57852 -const IS_FREE_LOCK = 57853 -const IS_USED_LOCK = 57854 -const LOCATE = 57855 -const POSITION = 57856 -const ST_GeometryCollectionFromText = 57857 -const ST_GeometryFromText = 57858 -const ST_LineStringFromText = 57859 -const ST_MultiLineStringFromText = 57860 -const ST_MultiPointFromText = 57861 -const ST_MultiPolygonFromText = 57862 -const ST_PointFromText = 57863 -const ST_PolygonFromText = 57864 -const ST_GeometryCollectionFromWKB = 57865 -const ST_GeometryFromWKB = 57866 -const ST_LineStringFromWKB = 57867 -const ST_MultiLineStringFromWKB = 57868 -const ST_MultiPointFromWKB = 57869 -const ST_MultiPolygonFromWKB = 57870 -const ST_PointFromWKB = 57871 -const ST_PolygonFromWKB = 57872 -const ST_AsBinary = 57873 -const ST_AsText = 57874 -const ST_Dimension = 57875 -const ST_Envelope = 57876 -const ST_IsSimple = 57877 -const ST_IsEmpty = 57878 -const ST_GeometryType = 57879 -const ST_X = 57880 -const ST_Y = 57881 -const ST_Latitude = 57882 -const ST_Longitude = 57883 -const ST_EndPoint = 57884 -const ST_IsClosed = 57885 -const ST_Length = 57886 -const ST_NumPoints = 57887 -const ST_StartPoint = 57888 -const ST_PointN = 57889 -const ST_Area = 57890 -const ST_Centroid = 57891 -const ST_ExteriorRing = 57892 -const ST_InteriorRingN = 57893 -const ST_NumInteriorRings = 57894 -const ST_NumGeometries = 57895 -const ST_GeometryN = 57896 -const ST_LongFromGeoHash = 57897 -const ST_PointFromGeoHash = 57898 -const ST_LatFromGeoHash = 57899 -const ST_GeoHash = 57900 -const ST_AsGeoJSON = 57901 -const ST_GeomFromGeoJSON = 57902 -const MATCH = 57903 -const AGAINST = 57904 -const BOOLEAN = 57905 -const LANGUAGE = 57906 -const WITH = 57907 -const QUERY = 57908 -const EXPANSION = 57909 -const WITHOUT = 57910 -const VALIDATION = 57911 -const ROLLUP = 57912 -const UNUSED = 57913 -const ARRAY = 57914 -const BYTE = 57915 -const CUME_DIST = 57916 -const DESCRIPTION = 57917 -const DENSE_RANK = 57918 -const EMPTY = 57919 -const EXCEPT = 57920 -const FIRST_VALUE = 57921 -const GROUPING = 57922 -const GROUPS = 57923 -const JSON_TABLE = 57924 -const LAG = 57925 -const LAST_VALUE = 57926 -const LATERAL = 57927 -const LEAD = 57928 -const NTH_VALUE = 57929 -const NTILE = 57930 -const OF = 57931 -const OVER = 57932 -const PERCENT_RANK = 57933 -const RANK = 57934 -const RECURSIVE = 57935 -const ROW_NUMBER = 57936 -const SYSTEM = 57937 -const WINDOW = 57938 -const ACTIVE = 57939 -const ADMIN = 57940 -const AUTOEXTEND_SIZE = 57941 -const BUCKETS = 57942 -const CLONE = 57943 -const COLUMN_FORMAT = 57944 -const COMPONENT = 57945 -const DEFINITION = 57946 -const ENFORCED = 57947 -const ENGINE_ATTRIBUTE = 57948 -const EXCLUDE = 57949 -const FOLLOWING = 57950 -const GET_MASTER_PUBLIC_KEY = 57951 -const HISTOGRAM = 57952 -const HISTORY = 57953 -const INACTIVE = 57954 -const INVISIBLE = 57955 -const LOCKED = 57956 -const MASTER_COMPRESSION_ALGORITHMS = 57957 -const MASTER_PUBLIC_KEY_PATH = 57958 -const MASTER_TLS_CIPHERSUITES = 57959 -const MASTER_ZSTD_COMPRESSION_LEVEL = 57960 -const NESTED = 57961 -const NETWORK_NAMESPACE = 57962 -const NOWAIT = 57963 -const NULLS = 57964 -const OJ = 57965 -const OLD = 57966 -const OPTIONAL = 57967 -const ORDINALITY = 57968 -const ORGANIZATION = 57969 -const OTHERS = 57970 -const PARTIAL = 57971 -const PATH = 57972 -const PERSIST = 57973 -const PERSIST_ONLY = 57974 -const PRECEDING = 57975 -const PRIVILEGE_CHECKS_USER = 57976 -const PROCESS = 57977 -const RANDOM = 57978 -const REFERENCE = 57979 -const REQUIRE_ROW_FORMAT = 57980 -const RESOURCE = 57981 -const RESPECT = 57982 -const RESTART = 57983 -const RETAIN = 57984 -const REUSE = 57985 -const ROLE = 57986 -const SECONDARY = 57987 -const SECONDARY_ENGINE = 57988 -const SECONDARY_ENGINE_ATTRIBUTE = 57989 -const SECONDARY_LOAD = 57990 -const SECONDARY_UNLOAD = 57991 -const SIMPLE = 57992 -const SKIP = 57993 -const SRID = 57994 -const THREAD_PRIORITY = 57995 -const TIES = 57996 -const UNBOUNDED = 57997 -const VCPU = 57998 -const VISIBLE = 57999 -const RETURNING = 58000 -const FORMAT_BYTES = 58001 -const FORMAT_PICO_TIME = 58002 -const PS_CURRENT_THREAD_ID = 58003 -const PS_THREAD_ID = 58004 -const GTID_SUBSET = 58005 -const GTID_SUBTRACT = 58006 -const WAIT_FOR_EXECUTED_GTID_SET = 58007 -const WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS = 58008 -const FORMAT = 58009 -const TREE = 58010 -const VITESS = 58011 -const TRADITIONAL = 58012 -const VTEXPLAIN = 58013 -const VEXPLAIN = 58014 -const PLAN = 58015 -const LOCAL = 58016 -const LOW_PRIORITY = 58017 -const NO_WRITE_TO_BINLOG = 58018 -const LOGS = 58019 -const ERROR = 58020 -const GENERAL = 58021 -const HOSTS = 58022 -const OPTIMIZER_COSTS = 58023 -const USER_RESOURCES = 58024 -const SLOW = 58025 -const CHANNEL = 58026 -const RELAY = 58027 -const EXPORT = 58028 -const CURRENT = 58029 -const ROW = 58030 -const ROWS = 58031 -const AVG_ROW_LENGTH = 58032 -const CONNECTION = 58033 -const CHECKSUM = 58034 -const DELAY_KEY_WRITE = 58035 -const ENCRYPTION = 58036 -const ENGINE = 58037 -const INSERT_METHOD = 58038 -const MAX_ROWS = 58039 -const MIN_ROWS = 58040 -const PACK_KEYS = 58041 -const PASSWORD = 58042 -const FIXED = 58043 -const DYNAMIC = 58044 -const COMPRESSED = 58045 -const REDUNDANT = 58046 -const COMPACT = 58047 -const ROW_FORMAT = 58048 -const STATS_AUTO_RECALC = 58049 -const STATS_PERSISTENT = 58050 -const STATS_SAMPLE_PAGES = 58051 -const STORAGE = 58052 -const MEMORY = 58053 -const DISK = 58054 -const PARTITIONS = 58055 -const LINEAR = 58056 -const RANGE = 58057 -const LIST = 58058 -const SUBPARTITION = 58059 -const SUBPARTITIONS = 58060 -const HASH = 58061 +const ALL = 57382 +const ANY = 57383 +const SOME = 57384 +const DISTINCTROW = 57385 +const PARSER = 57386 +const GENERATED = 57387 +const ALWAYS = 57388 +const OUTFILE = 57389 +const S3 = 57390 +const DATA = 57391 +const LOAD = 57392 +const LINES = 57393 +const TERMINATED = 57394 +const ESCAPED = 57395 +const ENCLOSED = 57396 +const DUMPFILE = 57397 +const CSV = 57398 +const HEADER = 57399 +const MANIFEST = 57400 +const OVERWRITE = 57401 +const STARTING = 57402 +const OPTIONALLY = 57403 +const VALUES = 57404 +const LAST_INSERT_ID = 57405 +const NEXT = 57406 +const VALUE = 57407 +const SHARE = 57408 +const MODE = 57409 +const SQL_NO_CACHE = 57410 +const SQL_CACHE = 57411 +const SQL_CALC_FOUND_ROWS = 57412 +const JOIN = 57413 +const STRAIGHT_JOIN = 57414 +const LEFT = 57415 +const RIGHT = 57416 +const INNER = 57417 +const OUTER = 57418 +const CROSS = 57419 +const NATURAL = 57420 +const USE = 57421 +const FORCE = 57422 +const ON = 57423 +const USING = 57424 +const INPLACE = 57425 +const COPY = 57426 +const INSTANT = 57427 +const ALGORITHM = 57428 +const NONE = 57429 +const SHARED = 57430 +const EXCLUSIVE = 57431 +const SUBQUERY_AS_EXPR = 57432 +const STRING = 57433 +const ID = 57434 +const AT_ID = 57435 +const AT_AT_ID = 57436 +const HEX = 57437 +const NCHAR_STRING = 57438 +const INTEGRAL = 57439 +const FLOAT = 57440 +const DECIMAL = 57441 +const HEXNUM = 57442 +const COMMENT = 57443 +const COMMENT_KEYWORD = 57444 +const BITNUM = 57445 +const BIT_LITERAL = 57446 +const COMPRESSION = 57447 +const VALUE_ARG = 57448 +const LIST_ARG = 57449 +const OFFSET_ARG = 57450 +const JSON_PRETTY = 57451 +const JSON_STORAGE_SIZE = 57452 +const JSON_STORAGE_FREE = 57453 +const JSON_CONTAINS = 57454 +const JSON_CONTAINS_PATH = 57455 +const JSON_EXTRACT = 57456 +const JSON_KEYS = 57457 +const JSON_OVERLAPS = 57458 +const JSON_SEARCH = 57459 +const JSON_VALUE = 57460 +const EXTRACT = 57461 +const NULL = 57462 +const UNKNOWN = 57463 +const TRUE = 57464 +const FALSE = 57465 +const OFF = 57466 +const DISCARD = 57467 +const IMPORT = 57468 +const ENABLE = 57469 +const DISABLE = 57470 +const TABLESPACE = 57471 +const VIRTUAL = 57472 +const STORED = 57473 +const BOTH = 57474 +const LEADING = 57475 +const TRAILING = 57476 +const KILL = 57477 +const EMPTY_FROM_CLAUSE = 57478 +const LOWER_THAN_CHARSET = 57479 +const CHARSET = 57480 +const UNIQUE = 57481 +const KEY = 57482 +const EXPRESSION_PREC_SETTER = 57483 +const OR = 57484 +const XOR = 57485 +const AND = 57486 +const NOT = 57487 +const BETWEEN = 57488 +const CASE = 57489 +const WHEN = 57490 +const THEN = 57491 +const ELSE = 57492 +const END = 57493 +const LE = 57494 +const GE = 57495 +const NE = 57496 +const NULL_SAFE_EQUAL = 57497 +const IS = 57498 +const LIKE = 57499 +const REGEXP = 57500 +const RLIKE = 57501 +const IN = 57502 +const ASSIGNMENT_OPT = 57503 +const SHIFT_LEFT = 57504 +const SHIFT_RIGHT = 57505 +const DIV = 57506 +const MOD = 57507 +const UNARY = 57508 +const COLLATE = 57509 +const BINARY = 57510 +const UNDERSCORE_ARMSCII8 = 57511 +const UNDERSCORE_ASCII = 57512 +const UNDERSCORE_BIG5 = 57513 +const UNDERSCORE_BINARY = 57514 +const UNDERSCORE_CP1250 = 57515 +const UNDERSCORE_CP1251 = 57516 +const UNDERSCORE_CP1256 = 57517 +const UNDERSCORE_CP1257 = 57518 +const UNDERSCORE_CP850 = 57519 +const UNDERSCORE_CP852 = 57520 +const UNDERSCORE_CP866 = 57521 +const UNDERSCORE_CP932 = 57522 +const UNDERSCORE_DEC8 = 57523 +const UNDERSCORE_EUCJPMS = 57524 +const UNDERSCORE_EUCKR = 57525 +const UNDERSCORE_GB18030 = 57526 +const UNDERSCORE_GB2312 = 57527 +const UNDERSCORE_GBK = 57528 +const UNDERSCORE_GEOSTD8 = 57529 +const UNDERSCORE_GREEK = 57530 +const UNDERSCORE_HEBREW = 57531 +const UNDERSCORE_HP8 = 57532 +const UNDERSCORE_KEYBCS2 = 57533 +const UNDERSCORE_KOI8R = 57534 +const UNDERSCORE_KOI8U = 57535 +const UNDERSCORE_LATIN1 = 57536 +const UNDERSCORE_LATIN2 = 57537 +const UNDERSCORE_LATIN5 = 57538 +const UNDERSCORE_LATIN7 = 57539 +const UNDERSCORE_MACCE = 57540 +const UNDERSCORE_MACROMAN = 57541 +const UNDERSCORE_SJIS = 57542 +const UNDERSCORE_SWE7 = 57543 +const UNDERSCORE_TIS620 = 57544 +const UNDERSCORE_UCS2 = 57545 +const UNDERSCORE_UJIS = 57546 +const UNDERSCORE_UTF16 = 57547 +const UNDERSCORE_UTF16LE = 57548 +const UNDERSCORE_UTF32 = 57549 +const UNDERSCORE_UTF8 = 57550 +const UNDERSCORE_UTF8MB4 = 57551 +const UNDERSCORE_UTF8MB3 = 57552 +const INTERVAL = 57553 +const WINDOW_EXPR = 57554 +const JSON_EXTRACT_OP = 57555 +const JSON_UNQUOTE_EXTRACT_OP = 57556 +const CREATE = 57557 +const ALTER = 57558 +const DROP = 57559 +const RENAME = 57560 +const ANALYZE = 57561 +const ADD = 57562 +const FLUSH = 57563 +const CHANGE = 57564 +const MODIFY = 57565 +const DEALLOCATE = 57566 +const REVERT = 57567 +const QUERIES = 57568 +const SCHEMA = 57569 +const TABLE = 57570 +const INDEX = 57571 +const VIEW = 57572 +const TO = 57573 +const IGNORE = 57574 +const IF = 57575 +const PRIMARY = 57576 +const COLUMN = 57577 +const SPATIAL = 57578 +const FULLTEXT = 57579 +const KEY_BLOCK_SIZE = 57580 +const CHECK = 57581 +const INDEXES = 57582 +const ACTION = 57583 +const CASCADE = 57584 +const CONSTRAINT = 57585 +const FOREIGN = 57586 +const NO = 57587 +const REFERENCES = 57588 +const RESTRICT = 57589 +const SHOW = 57590 +const DESCRIBE = 57591 +const EXPLAIN = 57592 +const DATE = 57593 +const ESCAPE = 57594 +const REPAIR = 57595 +const OPTIMIZE = 57596 +const TRUNCATE = 57597 +const COALESCE = 57598 +const EXCHANGE = 57599 +const REBUILD = 57600 +const PARTITIONING = 57601 +const REMOVE = 57602 +const PREPARE = 57603 +const EXECUTE = 57604 +const MAXVALUE = 57605 +const PARTITION = 57606 +const REORGANIZE = 57607 +const LESS = 57608 +const THAN = 57609 +const PROCEDURE = 57610 +const TRIGGER = 57611 +const VINDEX = 57612 +const VINDEXES = 57613 +const DIRECTORY = 57614 +const NAME = 57615 +const UPGRADE = 57616 +const STATUS = 57617 +const VARIABLES = 57618 +const WARNINGS = 57619 +const CASCADED = 57620 +const DEFINER = 57621 +const OPTION = 57622 +const SQL = 57623 +const UNDEFINED = 57624 +const SEQUENCE = 57625 +const MERGE = 57626 +const TEMPORARY = 57627 +const TEMPTABLE = 57628 +const INVOKER = 57629 +const SECURITY = 57630 +const FIRST = 57631 +const AFTER = 57632 +const LAST = 57633 +const VITESS_MIGRATION = 57634 +const CANCEL = 57635 +const RETRY = 57636 +const LAUNCH = 57637 +const COMPLETE = 57638 +const CLEANUP = 57639 +const THROTTLE = 57640 +const UNTHROTTLE = 57641 +const FORCE_CUTOVER = 57642 +const EXPIRE = 57643 +const RATIO = 57644 +const VITESS_THROTTLER = 57645 +const BEGIN = 57646 +const START = 57647 +const TRANSACTION = 57648 +const COMMIT = 57649 +const ROLLBACK = 57650 +const SAVEPOINT = 57651 +const RELEASE = 57652 +const WORK = 57653 +const CONSISTENT = 57654 +const SNAPSHOT = 57655 +const BIT = 57656 +const TINYINT = 57657 +const SMALLINT = 57658 +const MEDIUMINT = 57659 +const INT = 57660 +const INTEGER = 57661 +const BIGINT = 57662 +const INTNUM = 57663 +const REAL = 57664 +const DOUBLE = 57665 +const FLOAT_TYPE = 57666 +const FLOAT4_TYPE = 57667 +const FLOAT8_TYPE = 57668 +const DECIMAL_TYPE = 57669 +const NUMERIC = 57670 +const TIME = 57671 +const TIMESTAMP = 57672 +const DATETIME = 57673 +const YEAR = 57674 +const CHAR = 57675 +const VARCHAR = 57676 +const BOOL = 57677 +const CHARACTER = 57678 +const VARBINARY = 57679 +const NCHAR = 57680 +const TEXT = 57681 +const TINYTEXT = 57682 +const MEDIUMTEXT = 57683 +const LONGTEXT = 57684 +const BLOB = 57685 +const TINYBLOB = 57686 +const MEDIUMBLOB = 57687 +const LONGBLOB = 57688 +const JSON = 57689 +const JSON_SCHEMA_VALID = 57690 +const JSON_SCHEMA_VALIDATION_REPORT = 57691 +const ENUM = 57692 +const GEOMETRY = 57693 +const POINT = 57694 +const LINESTRING = 57695 +const POLYGON = 57696 +const GEOMCOLLECTION = 57697 +const GEOMETRYCOLLECTION = 57698 +const MULTIPOINT = 57699 +const MULTILINESTRING = 57700 +const MULTIPOLYGON = 57701 +const ASCII = 57702 +const UNICODE = 57703 +const NULLX = 57704 +const AUTO_INCREMENT = 57705 +const APPROXNUM = 57706 +const SIGNED = 57707 +const UNSIGNED = 57708 +const ZEROFILL = 57709 +const PURGE = 57710 +const BEFORE = 57711 +const CODE = 57712 +const COLLATION = 57713 +const COLUMNS = 57714 +const DATABASES = 57715 +const ENGINES = 57716 +const EVENT = 57717 +const EXTENDED = 57718 +const FIELDS = 57719 +const FULL = 57720 +const FUNCTION = 57721 +const GTID_EXECUTED = 57722 +const KEYSPACES = 57723 +const OPEN = 57724 +const PLUGINS = 57725 +const PRIVILEGES = 57726 +const PROCESSLIST = 57727 +const SCHEMAS = 57728 +const TABLES = 57729 +const TRIGGERS = 57730 +const USER = 57731 +const VGTID_EXECUTED = 57732 +const VITESS_KEYSPACES = 57733 +const VITESS_METADATA = 57734 +const VITESS_MIGRATIONS = 57735 +const VITESS_REPLICATION_STATUS = 57736 +const VITESS_SHARDS = 57737 +const VITESS_TABLETS = 57738 +const VITESS_TARGET = 57739 +const VSCHEMA = 57740 +const VITESS_THROTTLED_APPS = 57741 +const NAMES = 57742 +const GLOBAL = 57743 +const SESSION = 57744 +const ISOLATION = 57745 +const LEVEL = 57746 +const READ = 57747 +const WRITE = 57748 +const ONLY = 57749 +const REPEATABLE = 57750 +const COMMITTED = 57751 +const UNCOMMITTED = 57752 +const SERIALIZABLE = 57753 +const ADDDATE = 57754 +const CURRENT_TIMESTAMP = 57755 +const DATABASE = 57756 +const CURRENT_DATE = 57757 +const CURDATE = 57758 +const DATE_ADD = 57759 +const DATE_SUB = 57760 +const NOW = 57761 +const SUBDATE = 57762 +const CURTIME = 57763 +const CURRENT_TIME = 57764 +const LOCALTIME = 57765 +const LOCALTIMESTAMP = 57766 +const CURRENT_USER = 57767 +const UTC_DATE = 57768 +const UTC_TIME = 57769 +const UTC_TIMESTAMP = 57770 +const SYSDATE = 57771 +const DAY = 57772 +const DAY_HOUR = 57773 +const DAY_MICROSECOND = 57774 +const DAY_MINUTE = 57775 +const DAY_SECOND = 57776 +const HOUR = 57777 +const HOUR_MICROSECOND = 57778 +const HOUR_MINUTE = 57779 +const HOUR_SECOND = 57780 +const MICROSECOND = 57781 +const MINUTE = 57782 +const MINUTE_MICROSECOND = 57783 +const MINUTE_SECOND = 57784 +const MONTH = 57785 +const QUARTER = 57786 +const SECOND = 57787 +const SECOND_MICROSECOND = 57788 +const YEAR_MONTH = 57789 +const WEEK = 57790 +const SQL_TSI_DAY = 57791 +const SQL_TSI_WEEK = 57792 +const SQL_TSI_HOUR = 57793 +const SQL_TSI_MINUTE = 57794 +const SQL_TSI_MONTH = 57795 +const SQL_TSI_QUARTER = 57796 +const SQL_TSI_SECOND = 57797 +const SQL_TSI_MICROSECOND = 57798 +const SQL_TSI_YEAR = 57799 +const REPLACE = 57800 +const CONVERT = 57801 +const CAST = 57802 +const SUBSTR = 57803 +const SUBSTRING = 57804 +const MID = 57805 +const SEPARATOR = 57806 +const TIMESTAMPADD = 57807 +const TIMESTAMPDIFF = 57808 +const WEIGHT_STRING = 57809 +const LTRIM = 57810 +const RTRIM = 57811 +const TRIM = 57812 +const JSON_ARRAY = 57813 +const JSON_OBJECT = 57814 +const JSON_QUOTE = 57815 +const JSON_DEPTH = 57816 +const JSON_TYPE = 57817 +const JSON_LENGTH = 57818 +const JSON_VALID = 57819 +const JSON_ARRAY_APPEND = 57820 +const JSON_ARRAY_INSERT = 57821 +const JSON_INSERT = 57822 +const JSON_MERGE = 57823 +const JSON_MERGE_PATCH = 57824 +const JSON_MERGE_PRESERVE = 57825 +const JSON_REMOVE = 57826 +const JSON_REPLACE = 57827 +const JSON_SET = 57828 +const JSON_UNQUOTE = 57829 +const COUNT = 57830 +const AVG = 57831 +const MAX = 57832 +const MIN = 57833 +const SUM = 57834 +const GROUP_CONCAT = 57835 +const BIT_AND = 57836 +const BIT_OR = 57837 +const BIT_XOR = 57838 +const STD = 57839 +const STDDEV = 57840 +const STDDEV_POP = 57841 +const STDDEV_SAMP = 57842 +const VAR_POP = 57843 +const VAR_SAMP = 57844 +const VARIANCE = 57845 +const ANY_VALUE = 57846 +const REGEXP_INSTR = 57847 +const REGEXP_LIKE = 57848 +const REGEXP_REPLACE = 57849 +const REGEXP_SUBSTR = 57850 +const ExtractValue = 57851 +const UpdateXML = 57852 +const GET_LOCK = 57853 +const RELEASE_LOCK = 57854 +const RELEASE_ALL_LOCKS = 57855 +const IS_FREE_LOCK = 57856 +const IS_USED_LOCK = 57857 +const LOCATE = 57858 +const POSITION = 57859 +const ST_GeometryCollectionFromText = 57860 +const ST_GeometryFromText = 57861 +const ST_LineStringFromText = 57862 +const ST_MultiLineStringFromText = 57863 +const ST_MultiPointFromText = 57864 +const ST_MultiPolygonFromText = 57865 +const ST_PointFromText = 57866 +const ST_PolygonFromText = 57867 +const ST_GeometryCollectionFromWKB = 57868 +const ST_GeometryFromWKB = 57869 +const ST_LineStringFromWKB = 57870 +const ST_MultiLineStringFromWKB = 57871 +const ST_MultiPointFromWKB = 57872 +const ST_MultiPolygonFromWKB = 57873 +const ST_PointFromWKB = 57874 +const ST_PolygonFromWKB = 57875 +const ST_AsBinary = 57876 +const ST_AsText = 57877 +const ST_Dimension = 57878 +const ST_Envelope = 57879 +const ST_IsSimple = 57880 +const ST_IsEmpty = 57881 +const ST_GeometryType = 57882 +const ST_X = 57883 +const ST_Y = 57884 +const ST_Latitude = 57885 +const ST_Longitude = 57886 +const ST_EndPoint = 57887 +const ST_IsClosed = 57888 +const ST_Length = 57889 +const ST_NumPoints = 57890 +const ST_StartPoint = 57891 +const ST_PointN = 57892 +const ST_Area = 57893 +const ST_Centroid = 57894 +const ST_ExteriorRing = 57895 +const ST_InteriorRingN = 57896 +const ST_NumInteriorRings = 57897 +const ST_NumGeometries = 57898 +const ST_GeometryN = 57899 +const ST_LongFromGeoHash = 57900 +const ST_PointFromGeoHash = 57901 +const ST_LatFromGeoHash = 57902 +const ST_GeoHash = 57903 +const ST_AsGeoJSON = 57904 +const ST_GeomFromGeoJSON = 57905 +const MATCH = 57906 +const AGAINST = 57907 +const BOOLEAN = 57908 +const LANGUAGE = 57909 +const WITH = 57910 +const QUERY = 57911 +const EXPANSION = 57912 +const WITHOUT = 57913 +const VALIDATION = 57914 +const ROLLUP = 57915 +const UNUSED = 57916 +const ARRAY = 57917 +const BYTE = 57918 +const CUME_DIST = 57919 +const DESCRIPTION = 57920 +const DENSE_RANK = 57921 +const EMPTY = 57922 +const EXCEPT = 57923 +const FIRST_VALUE = 57924 +const GROUPING = 57925 +const GROUPS = 57926 +const JSON_TABLE = 57927 +const LAG = 57928 +const LAST_VALUE = 57929 +const LATERAL = 57930 +const LEAD = 57931 +const NTH_VALUE = 57932 +const NTILE = 57933 +const OF = 57934 +const OVER = 57935 +const PERCENT_RANK = 57936 +const RANK = 57937 +const RECURSIVE = 57938 +const ROW_NUMBER = 57939 +const SYSTEM = 57940 +const WINDOW = 57941 +const ACTIVE = 57942 +const ADMIN = 57943 +const AUTOEXTEND_SIZE = 57944 +const BUCKETS = 57945 +const CLONE = 57946 +const COLUMN_FORMAT = 57947 +const COMPONENT = 57948 +const DEFINITION = 57949 +const ENFORCED = 57950 +const ENGINE_ATTRIBUTE = 57951 +const EXCLUDE = 57952 +const FOLLOWING = 57953 +const GET_MASTER_PUBLIC_KEY = 57954 +const HISTOGRAM = 57955 +const HISTORY = 57956 +const INACTIVE = 57957 +const INVISIBLE = 57958 +const LOCKED = 57959 +const MASTER_COMPRESSION_ALGORITHMS = 57960 +const MASTER_PUBLIC_KEY_PATH = 57961 +const MASTER_TLS_CIPHERSUITES = 57962 +const MASTER_ZSTD_COMPRESSION_LEVEL = 57963 +const NESTED = 57964 +const NETWORK_NAMESPACE = 57965 +const NOWAIT = 57966 +const NULLS = 57967 +const OJ = 57968 +const OLD = 57969 +const OPTIONAL = 57970 +const ORDINALITY = 57971 +const ORGANIZATION = 57972 +const OTHERS = 57973 +const PARTIAL = 57974 +const PATH = 57975 +const PERSIST = 57976 +const PERSIST_ONLY = 57977 +const PRECEDING = 57978 +const PRIVILEGE_CHECKS_USER = 57979 +const PROCESS = 57980 +const RANDOM = 57981 +const REFERENCE = 57982 +const REQUIRE_ROW_FORMAT = 57983 +const RESOURCE = 57984 +const RESPECT = 57985 +const RESTART = 57986 +const RETAIN = 57987 +const REUSE = 57988 +const ROLE = 57989 +const SECONDARY = 57990 +const SECONDARY_ENGINE = 57991 +const SECONDARY_ENGINE_ATTRIBUTE = 57992 +const SECONDARY_LOAD = 57993 +const SECONDARY_UNLOAD = 57994 +const SIMPLE = 57995 +const SKIP = 57996 +const SRID = 57997 +const THREAD_PRIORITY = 57998 +const TIES = 57999 +const UNBOUNDED = 58000 +const VCPU = 58001 +const VISIBLE = 58002 +const RETURNING = 58003 +const FORMAT_BYTES = 58004 +const FORMAT_PICO_TIME = 58005 +const PS_CURRENT_THREAD_ID = 58006 +const PS_THREAD_ID = 58007 +const GTID_SUBSET = 58008 +const GTID_SUBTRACT = 58009 +const WAIT_FOR_EXECUTED_GTID_SET = 58010 +const WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS = 58011 +const FORMAT = 58012 +const TREE = 58013 +const VITESS = 58014 +const TRADITIONAL = 58015 +const VTEXPLAIN = 58016 +const VEXPLAIN = 58017 +const PLAN = 58018 +const LOCAL = 58019 +const LOW_PRIORITY = 58020 +const NO_WRITE_TO_BINLOG = 58021 +const LOGS = 58022 +const ERROR = 58023 +const GENERAL = 58024 +const HOSTS = 58025 +const OPTIMIZER_COSTS = 58026 +const USER_RESOURCES = 58027 +const SLOW = 58028 +const CHANNEL = 58029 +const RELAY = 58030 +const EXPORT = 58031 +const CURRENT = 58032 +const ROW = 58033 +const ROWS = 58034 +const AVG_ROW_LENGTH = 58035 +const CONNECTION = 58036 +const CHECKSUM = 58037 +const DELAY_KEY_WRITE = 58038 +const ENCRYPTION = 58039 +const ENGINE = 58040 +const INSERT_METHOD = 58041 +const MAX_ROWS = 58042 +const MIN_ROWS = 58043 +const PACK_KEYS = 58044 +const PASSWORD = 58045 +const FIXED = 58046 +const DYNAMIC = 58047 +const COMPRESSED = 58048 +const REDUNDANT = 58049 +const COMPACT = 58050 +const ROW_FORMAT = 58051 +const STATS_AUTO_RECALC = 58052 +const STATS_PERSISTENT = 58053 +const STATS_SAMPLE_PAGES = 58054 +const STORAGE = 58055 +const MEMORY = 58056 +const DISK = 58057 +const PARTITIONS = 58058 +const LINEAR = 58059 +const RANGE = 58060 +const LIST = 58061 +const SUBPARTITION = 58062 +const SUBPARTITIONS = 58063 +const HASH = 58064 var yyToknames = [...]string{ "$end", @@ -760,6 +763,7 @@ var yyToknames = [...]string{ "MULTIPLE_TEXT_LITERAL", "FUNCTION_CALL_NON_KEYWORD", "STRING_TYPE_PREFIX_NON_KEYWORD", + "ANY_SOME", "LEX_ERROR", "UNION", "SELECT", @@ -777,7 +781,6 @@ var yyToknames = [...]string{ "LIMIT", "OFFSET", "FOR", - "ALL", "DISTINCT", "AS", "EXISTS", @@ -792,6 +795,9 @@ var yyToknames = [...]string{ "KEYS", "DO", "CALL", + "ALL", + "ANY", + "SOME", "DISTINCTROW", "PARSER", "GENERATED", @@ -1504,124 +1510,121 @@ var yyExca = [...]int{ 1, -1, -2, 0, -1, 2, - 14, 49, 15, 49, + 16, 49, -2, 40, -1, 52, 1, 157, - 737, 157, + 740, 157, -2, 165, -1, 53, - 138, 165, - 180, 165, - 350, 165, + 141, 165, + 183, 165, + 353, 165, -2, 523, -1, 61, 37, 777, - 243, 777, - 254, 777, - 289, 791, - 290, 791, + 246, 777, + 257, 777, + 292, 791, + 293, 791, -2, 779, -1, 66, - 245, 815, + 248, 815, -2, 813, -1, 122, - 242, 1602, + 245, 1606, -2, 131, -1, 124, 1, 158, - 737, 158, + 740, 158, -2, 165, -1, 135, - 139, 408, - 248, 408, + 142, 408, + 251, 408, -2, 512, -1, 154, - 138, 165, - 180, 165, - 350, 165, + 141, 165, + 183, 165, + 353, 165, -2, 532, - -1, 737, - 166, 41, + -1, 739, + 169, 41, -2, 43, - -1, 944, - 88, 1619, - -2, 1463, - -1, 945, - 88, 1620, - 225, 1624, - -2, 1464, -1, 946, - 225, 1623, + 91, 1623, + -2, 1467, + -1, 947, + 91, 1624, + 228, 1628, + -2, 1468, + -1, 948, + 228, 1627, -2, 42, - -1, 1030, - 61, 887, + -1, 1032, + 64, 887, -2, 900, - -1, 1118, - 253, 1093, - 258, 1093, + -1, 1120, + 256, 1096, + 261, 1096, -2, 419, - -1, 1203, + -1, 1205, 1, 580, - 737, 580, + 740, 580, -2, 165, - -1, 1506, - 225, 1624, - -2, 1464, - -1, 1717, - 61, 888, + -1, 1509, + 228, 1628, + -2, 1468, + -1, 1720, + 64, 888, -2, 904, - -1, 1718, - 61, 889, + -1, 1721, + 64, 889, -2, 905, - -1, 1774, - 138, 165, - 180, 165, - 350, 165, + -1, 1777, + 141, 165, + 183, 165, + 353, 165, -2, 458, - -1, 1855, - 139, 408, - 248, 408, + -1, 1858, + 142, 408, + 251, 408, -2, 512, - -1, 1864, - 253, 1094, - 258, 1094, + -1, 1867, + 256, 1097, + 261, 1097, -2, 420, - -1, 2304, - 225, 1628, - -2, 1622, - -1, 2305, - 225, 1624, - -2, 1620, - -1, 2408, - 138, 165, - 180, 165, - 350, 165, + -1, 2310, + 228, 1632, + -2, 1626, + -1, 2311, + 228, 1628, + -2, 1624, + -1, 2414, + 141, 165, + 183, 165, + 353, 165, -2, 459, - -1, 2415, + -1, 2421, 27, 186, -2, 188, - -1, 2869, - 79, 96, - 89, 96, + -1, 2878, + 82, 96, + 92, 96, -2, 963, - -1, 2938, - 712, 700, + -1, 2947, + 715, 700, -2, 674, - -1, 3160, - 51, 1567, - -2, 1561, - -1, 3994, - 712, 700, + -1, 3169, + 54, 1571, + -2, 1565, + -1, 4003, + 715, 700, -2, 688, - -1, 4086, - 91, 632, - 96, 632, - 106, 632, - 182, 632, - 183, 632, - 184, 632, + -1, 4095, + 94, 632, + 99, 632, + 109, 632, 185, 632, 186, 632, 187, 632, @@ -1661,1114 +1664,1115 @@ var yyExca = [...]int{ 221, 632, 222, 632, 223, 632, - -2, 1993, + 224, 632, + 225, 632, + 226, 632, + -2, 1998, } const yyPrivate = 57344 -const yyLast = 56041 +const yyLast = 56205 var yyAct = [...]int{ - 960, 3647, 3648, 87, 3646, 4084, 4161, 3975, 948, 3312, - 4174, 4065, 4129, 4128, 1271, 955, 1984, 947, 2099, 3597, - 2405, 4053, 3957, 3212, 3219, 913, 3447, 3880, 42, 2333, - 2111, 3261, 3270, 3275, 3272, 1777, 3173, 3955, 3584, 3271, - 1269, 3269, 3028, 2040, 3274, 3273, 5, 2335, 3290, 3227, - 2479, 3111, 3289, 741, 3177, 3174, 3493, 3487, 3689, 3002, - 2829, 2360, 3171, 3477, 3161, 769, 3027, 735, 909, 2442, - 736, 4026, 908, 3292, 1833, 2903, 3319, 2984, 2935, 2467, - 1733, 2447, 1080, 2904, 2510, 2905, 1028, 2379, 87, 163, - 2376, 2393, 1048, 2854, 1025, 43, 2835, 1055, 2381, 1126, - 1880, 2821, 2257, 2048, 3515, 1150, 41, 1028, 2805, 2380, - 2256, 1027, 2095, 1031, 2289, 2488, 2976, 1862, 149, 2466, - 2368, 2527, 1090, 2133, 2449, 2896, 1113, 1108, 1766, 2871, - 2383, 1746, 1050, 1698, 1519, 104, 2139, 105, 2070, 2062, - 1445, 100, 1430, 1869, 1980, 1087, 3176, 751, 2464, 1084, - 1119, 1961, 1088, 2438, 1114, 1115, 1765, 1065, 2439, 1067, - 1751, 1116, 746, 1037, 3684, 1720, 2803, 1502, 2166, 2147, - 1478, 1034, 2039, 1259, 85, 2842, 1992, 3448, 132, 167, - 3504, 1047, 3676, 1033, 107, 2361, 127, 125, 126, 1854, - 133, 1199, 1023, 93, 1032, 1060, 910, 1035, 745, 739, - 1523, 738, 99, 1267, 98, 1245, 4162, 2481, 2482, 2483, - 1059, 3585, 3258, 1528, 4010, 84, 2481, 2958, 2957, 2525, - 2926, 3577, 1022, 4111, 106, 2992, 1946, 2993, 4006, 2055, - 4005, 2054, 128, 2330, 2331, 2053, 1130, 2052, 3540, 2051, - 4011, 1040, 728, 134, 1155, 2050, 1081, 673, 2023, 1215, - 670, 2801, 671, 2575, 4105, 3157, 4132, 1152, 1163, 4184, - 1441, 2514, 1097, 1092, 3651, 3115, 4127, 1737, 4152, 3451, - 1169, 1170, 1171, 3450, 1174, 1175, 1176, 1177, 2, 1074, - 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, - 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1738, 1129, 1462, - 1049, 1026, 1075, 1041, 128, 2513, 2831, 3984, 3280, 1024, - 1735, 1104, 1103, 1102, 1105, 729, 1216, 1156, 1159, 1160, - 2357, 3277, 2356, 111, 112, 113, 2928, 116, 713, 3280, - 122, 4006, 4167, 191, 2951, 2354, 665, 95, 95, 95, - 1736, 4115, 4113, 3958, 2766, 3651, 713, 1021, 726, 727, - 95, 3650, 914, 1172, 707, 2060, 2073, 4166, 1016, 1017, - 1018, 1019, 2948, 3338, 3278, 1030, 4114, 4112, 1073, 1077, - 912, 190, 128, 4080, 3876, 3875, 1154, 963, 964, 965, - 3590, 86, 1153, 3591, 4142, 3278, 3886, 4109, 86, 3609, - 1432, 3284, 707, 1062, 1063, 129, 1106, 190, 963, 964, - 965, 3598, 1727, 86, 4054, 2845, 4062, 2582, 172, 2507, - 3885, 2104, 3284, 4089, 707, 3364, 1843, 2802, 4094, 3209, - 3210, 129, 3208, 1073, 1077, 912, 1096, 2991, 4066, 1098, - 2846, 1767, 3650, 1768, 172, 704, 4092, 1459, 2399, 1460, - 1461, 2400, 2401, 2032, 2033, 2579, 4098, 4099, 1252, 2975, - 1254, 2885, 3703, 1264, 1198, 3229, 3230, 1235, 1101, 95, - 1208, 1209, 4093, 1014, 169, 2880, 95, 170, 2879, 707, - 1458, 2881, 2580, 1013, 3608, 1442, 3976, 1240, 1241, 1223, - 1236, 95, 2512, 689, 1224, 1229, 2892, 707, 1251, 1253, - 169, 189, 1211, 170, 1223, 3346, 687, 2418, 2417, 1224, - 1988, 2838, 2839, 3344, 4070, 3281, 2332, 1222, 3316, 1221, - 4133, 3049, 707, 3314, 2573, 2031, 1099, 189, 2035, 721, - 725, 719, 1763, 3320, 1446, 4070, 3281, 3989, 1101, 1173, - 1093, 4134, 1702, 2977, 2936, 2489, 684, 1095, 1094, 707, - 3928, 1936, 3929, 2961, 2551, 699, 2552, 2528, 2553, 3307, - 1962, 86, 2532, 1431, 88, 2364, 2534, 3308, 1256, 4164, - 694, 1238, 1239, 1263, 3228, 2458, 708, 1261, 1244, 1262, - 3860, 697, 1204, 2979, 3579, 1237, 3231, 2576, 3578, 2577, - 1230, 1847, 1242, 2554, 1179, 1937, 1099, 1938, 2452, 1178, - 2530, 1479, 1243, 1128, 2531, 1249, 1066, 3575, 1128, 1250, - 2492, 3317, 2929, 1139, 708, 173, 3315, 2533, 1109, 1255, - 2175, 2535, 1110, 3335, 179, 1480, 1481, 1482, 1483, 1484, - 1485, 1486, 1488, 1487, 1489, 1490, 708, 1149, 3655, 95, - 2377, 173, 1456, 1110, 1248, 2965, 2966, 1148, 1989, 674, - 179, 676, 690, 1147, 710, 1100, 709, 680, 1146, 678, - 682, 691, 683, 4106, 677, 1145, 688, 1144, 1143, 679, - 692, 693, 696, 700, 701, 702, 698, 695, 3490, 686, - 711, 3231, 1142, 1141, 1136, 1705, 3114, 3050, 4185, 4139, - 1085, 708, 2541, 2537, 2539, 2540, 2538, 2542, 2543, 2544, - 1076, 1070, 1068, 1085, 1121, 1061, 1127, 1981, 1122, 708, - 3251, 1127, 2465, 2960, 1268, 1085, 1268, 1268, 2167, 1083, - 1158, 2980, 3574, 2169, 2518, 1100, 1121, 2174, 2170, 1841, - 1157, 2171, 2172, 2173, 708, 2517, 2168, 2176, 2177, 2178, - 2179, 2180, 2181, 2182, 2183, 2184, 1977, 3142, 2451, 164, - 1433, 1452, 3140, 1166, 1444, 1076, 1070, 1068, 2362, 2363, - 1764, 708, 1140, 1840, 1028, 1503, 1508, 1509, 1839, 1512, - 1514, 1515, 1516, 1517, 1518, 164, 1521, 1522, 1524, 1524, - 2946, 1524, 1524, 1529, 1529, 1529, 1532, 1533, 1534, 1535, - 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, - 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, - 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, - 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, - 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, - 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, - 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, - 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, - 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, - 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, - 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, - 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1446, 1257, - 2930, 1500, 1654, 3983, 1656, 1657, 1658, 1659, 1660, 1424, - 1425, 1948, 1947, 1949, 1950, 1951, 1529, 1529, 1529, 1529, - 1529, 1529, 2927, 3538, 3539, 1440, 3649, 1107, 1210, 1207, - 1423, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, - 1676, 1677, 1678, 1679, 1680, 712, 4097, 1496, 1497, 1498, - 1499, 1504, 4068, 94, 961, 961, 961, 1510, 2511, 2950, - 94, 1513, 1695, 4029, 2894, 2581, 705, 1069, 3491, 1525, - 3435, 1526, 1527, 4068, 1868, 94, 3282, 3283, 165, 3607, - 1202, 706, 1220, 2963, 4067, 177, 1692, 1530, 1531, 3286, - 4096, 1219, 1137, 1225, 1226, 1227, 1228, 3282, 3283, 2580, - 1233, 1978, 1837, 2949, 165, 4067, 1456, 3649, 1493, 1214, - 3286, 177, 664, 89, 1128, 3123, 1701, 1265, 1266, 2509, - 1493, 2974, 1069, 4107, 2973, 1028, 185, 1494, 1495, 1028, - 3336, 1726, 2806, 2808, 1128, 1028, 3971, 1451, 1448, 1449, - 1450, 1455, 1457, 1454, 1967, 1453, 1128, 3529, 2983, 3511, - 1709, 2876, 185, 3122, 1713, 1447, 2841, 2778, 2107, 1128, - 1027, 1755, 1655, 1213, 4178, 2836, 672, 1693, 2455, 166, - 171, 168, 174, 175, 176, 178, 180, 181, 182, 183, - 2131, 2406, 1493, 1867, 1490, 184, 186, 187, 188, 124, - 3207, 2605, 1473, 707, 2996, 166, 171, 168, 174, 175, - 176, 178, 180, 181, 182, 183, 2594, 1044, 1246, 2456, - 1260, 184, 186, 187, 188, 1452, 2454, 1127, 1727, 1993, - 1711, 1966, 1712, 94, 104, 1218, 105, 1165, 3997, 1661, - 1662, 1663, 1664, 1665, 1666, 1693, 2364, 1127, 1101, 1197, - 119, 1138, 1131, 1121, 1699, 1151, 3570, 1133, 3503, 1127, - 2457, 1134, 1132, 2148, 1686, 1121, 1124, 1125, 2529, 1085, - 2453, 2044, 1127, 1118, 1122, 1974, 2986, 2149, 1121, 1124, - 1125, 2985, 1085, 107, 1769, 3023, 1118, 1122, 2123, 2112, - 2113, 2114, 2115, 2125, 2116, 2117, 2118, 2130, 2126, 2119, - 2120, 2127, 2128, 2129, 2121, 2122, 2124, 1117, 2605, 1860, - 2140, 2919, 2807, 1201, 3003, 1707, 1232, 3215, 2140, 4143, - 2614, 1844, 1845, 1846, 120, 2986, 2508, 1234, 1708, 1710, - 2985, 1460, 1461, 1461, 1870, 1870, 3698, 3545, 1986, 1128, - 1931, 1853, 4135, 1462, 1732, 1729, 3544, 1882, 2496, 1883, - 1128, 1885, 1887, 1913, 1872, 1891, 1893, 1895, 1897, 1899, - 1026, 1024, 3216, 1877, 1876, 1696, 1268, 1247, 1760, 1761, - 1970, 1828, 1968, 1969, 1866, 1971, 1972, 1973, 1994, 1871, - 1217, 2501, 1963, 2506, 1964, 2134, 3218, 1965, 1921, 1922, - 1462, 2504, 1203, 1836, 1927, 1928, 4176, 2501, 3005, 4177, - 1851, 4175, 2610, 1139, 3213, 1462, 1863, 1137, 4030, 2146, - 4186, 1850, 1849, 3530, 1039, 708, 4180, 2075, 1714, 1200, - 2294, 2505, 3868, 3229, 3230, 3867, 3963, 1462, 4148, 1727, - 3214, 2076, 1491, 1492, 2074, 1100, 1874, 2503, 3858, 2362, - 2363, 3621, 1127, 2066, 2067, 2587, 2588, 1131, 1121, 3604, - 2641, 3605, 1133, 1127, 4031, 1164, 1134, 1132, 3620, 1161, - 731, 3552, 1917, 1909, 3220, 1982, 1912, 3551, 1914, 3015, - 3014, 3013, 3964, 3541, 3007, 2609, 3011, 1135, 3006, 3259, - 3004, 1459, 3247, 1460, 1461, 3009, 1842, 1485, 1486, 1488, - 1487, 1489, 1490, 128, 3008, 2901, 2900, 4187, 1956, 2899, - 1104, 1103, 1102, 1483, 1484, 1485, 1486, 1488, 1487, 1489, - 1490, 2461, 3010, 3012, 1462, 3311, 1957, 1941, 1999, 1462, - 1954, 1451, 1448, 1449, 1450, 1455, 1457, 1454, 1459, 1453, - 1460, 1461, 3228, 1268, 1268, 1940, 1939, 1995, 1996, 1447, - 2021, 1727, 2601, 1459, 3231, 1460, 1461, 87, 2145, 1929, - 87, 2000, 3025, 2066, 2067, 2064, 2065, 1923, 2007, 2008, - 2009, 1479, 1955, 1427, 1475, 1459, 1476, 1460, 1461, 2020, - 1920, 1919, 42, 1918, 1479, 42, 2995, 1889, 1706, 2063, - 1477, 1491, 1492, 1474, 1953, 1480, 1481, 1482, 1483, 1484, - 1485, 1486, 1488, 1487, 1489, 1490, 3535, 713, 1480, 1481, - 1482, 1483, 1484, 1485, 1486, 1488, 1487, 1489, 1490, 1479, - 1481, 1482, 1483, 1484, 1485, 1486, 1488, 1487, 1489, 1490, - 2102, 2102, 2100, 2100, 2103, 963, 964, 965, 713, 4136, - 1462, 2653, 1763, 1480, 1481, 1482, 1483, 1484, 1485, 1486, - 1488, 1487, 1489, 1490, 2883, 713, 2068, 2477, 2476, 1479, - 1692, 2593, 1459, 1943, 1460, 1461, 1997, 1459, 3992, 1460, - 1461, 3217, 3991, 2001, 3967, 2003, 2004, 2005, 2006, 1479, - 3966, 1462, 2010, 1480, 1481, 1482, 1483, 1484, 1485, 1486, - 1488, 1487, 1489, 1490, 2022, 2475, 2474, 2473, 2472, 2827, - 4163, 3353, 2186, 1480, 1481, 1482, 1483, 1484, 1485, 1486, - 1488, 1487, 1489, 1490, 1480, 1481, 1482, 1483, 1484, 1485, - 1486, 1488, 1487, 1489, 1490, 4146, 1727, 1942, 85, 1462, - 3965, 85, 2045, 1466, 1467, 1468, 1469, 1470, 1471, 1472, - 1464, 1693, 2072, 2651, 1462, 2294, 2028, 2029, 1462, 2291, - 110, 110, 3863, 1458, 1727, 1462, 4123, 1727, 2293, 1462, - 2135, 109, 109, 108, 108, 3847, 2077, 1727, 2827, 1727, - 1462, 1740, 959, 103, 1462, 3846, 101, 101, 1459, 3697, - 1460, 1461, 3695, 103, 1458, 1727, 1727, 102, 102, 1462, - 2304, 2106, 2303, 2827, 4061, 2827, 4040, 2079, 2078, 3617, - 2080, 2081, 2082, 2083, 2084, 2085, 2087, 2089, 2090, 2091, - 2092, 2093, 2094, 2208, 4076, 1727, 2302, 1741, 1691, 1459, - 1504, 1460, 1461, 2150, 2151, 2152, 2153, 2827, 4036, 4074, - 1727, 1727, 1727, 4072, 1727, 2292, 2290, 2164, 2141, 2185, - 3941, 1727, 1727, 1727, 3939, 1727, 3948, 1727, 3588, 3982, - 3871, 1727, 1462, 2827, 3859, 3936, 1727, 3502, 1690, 3918, - 1727, 1458, 1689, 1462, 3588, 1727, 3985, 1459, 3549, 1460, - 1461, 2827, 3586, 3895, 3476, 1727, 4024, 3534, 2501, 1727, - 1462, 2385, 1459, 2200, 1460, 1461, 1459, 3321, 1460, 1461, - 2304, 3318, 2374, 1459, 1462, 1460, 1461, 1459, 2301, 1460, - 1461, 2307, 2308, 3509, 1727, 104, 2387, 105, 1459, 3250, - 1460, 1461, 1459, 3221, 1460, 1461, 2302, 3225, 2415, 2369, - 2370, 2733, 1727, 1462, 3224, 3249, 104, 1459, 105, 1460, - 1461, 3240, 3239, 3894, 2349, 3237, 3238, 3469, 1727, 1462, - 3235, 3236, 3851, 1462, 2910, 2337, 2897, 2071, 3466, 1727, - 3235, 3234, 103, 1090, 2851, 1727, 2580, 2959, 3226, 1832, - 2940, 2933, 2934, 3222, 1688, 3464, 1727, 3850, 3223, 1681, - 2424, 2425, 2426, 2427, 2564, 2872, 2872, 2419, 2410, 2420, - 2421, 2422, 2423, 2563, 2409, 2391, 1090, 1462, 2827, 2826, - 1459, 1040, 1460, 1461, 2523, 2430, 2431, 2432, 2433, 2105, - 1727, 1459, 2522, 1460, 1461, 2350, 2359, 2338, 3427, 1727, - 3596, 1727, 2343, 2024, 2344, 2352, 2325, 2444, 1459, 1990, - 1460, 1461, 2413, 1952, 3425, 1727, 3996, 1944, 3421, 1727, - 2490, 2450, 1459, 2372, 1460, 1461, 1934, 1462, 2873, 2873, - 2396, 2397, 2395, 1930, 1926, 1074, 1925, 1924, 2875, 2580, - 2412, 2411, 1462, 1832, 1831, 109, 1462, 1775, 1774, 3202, - 1462, 1459, 2487, 1460, 1461, 1742, 1258, 2843, 1075, 2580, - 2824, 2937, 3418, 1727, 2460, 1462, 2915, 1459, 1130, 1460, - 1461, 1459, 1462, 1460, 1461, 103, 3506, 2843, 1870, 1462, - 2414, 2827, 86, 44, 45, 88, 2851, 2850, 2445, 2441, - 2434, 2436, 2437, 3172, 2495, 2459, 3455, 2498, 2463, 2499, - 3237, 2471, 92, 3145, 3502, 2515, 48, 76, 77, 1462, - 74, 78, 3416, 1727, 1458, 1459, 1462, 1460, 1461, 75, - 2502, 2494, 2497, 2445, 2493, 2398, 2733, 3414, 1727, 2851, - 1129, 3412, 1727, 2822, 2638, 3410, 1727, 2637, 3505, 2516, - 2519, 1462, 2851, 2501, 2520, 2521, 1462, 2484, 62, 3502, - 3408, 1727, 1462, 2367, 2603, 1731, 2328, 3406, 1727, 2105, - 95, 3262, 2046, 2030, 2602, 1459, 1976, 1460, 1461, 1762, - 1029, 2585, 1112, 2526, 1728, 1730, 1462, 1111, 2501, 95, - 1459, 1462, 1460, 1461, 1459, 4102, 1460, 1461, 1459, 3553, - 1460, 1461, 4043, 3313, 3404, 1727, 3882, 1514, 1734, 1514, - 1905, 3402, 1727, 1459, 3848, 1460, 1461, 83, 3710, 3569, - 1459, 3566, 1460, 1461, 1462, 2597, 3547, 1459, 3369, 1460, - 1461, 3368, 1834, 1462, 2443, 3883, 3400, 1727, 3309, 3264, - 1462, 3890, 2304, 2557, 2303, 3260, 2907, 3398, 1727, 1462, - 3554, 3555, 3556, 1462, 1479, 2941, 2440, 1459, 95, 1460, - 1461, 1906, 1907, 1908, 1459, 2458, 1460, 1461, 2600, 2435, - 2341, 3396, 1727, 2429, 1462, 1202, 3394, 1727, 1480, 1481, - 1482, 1483, 1484, 1485, 1486, 1488, 1487, 1489, 1490, 1459, - 1462, 1460, 1461, 2572, 1459, 2428, 1460, 1461, 1462, 1959, - 1459, 1865, 1460, 1461, 1861, 1830, 121, 2578, 4158, 3392, - 1727, 51, 54, 57, 56, 59, 4156, 73, 3390, 1727, - 82, 79, 2906, 2586, 1459, 3524, 1460, 1461, 4130, 1459, - 2026, 1460, 1461, 2589, 3388, 1727, 3516, 3517, 3374, 1727, - 4004, 1462, 2072, 3923, 61, 91, 90, 3519, 3522, 71, - 72, 58, 3256, 3255, 3254, 1462, 1694, 80, 81, 3351, - 1727, 3172, 1459, 2920, 1460, 1461, 2558, 1462, 669, 3557, - 2907, 1459, 1901, 1460, 1461, 2798, 1727, 1462, 1459, 3521, - 1460, 1461, 1739, 2796, 1727, 1462, 3191, 1459, 3190, 1460, - 1461, 1459, 2027, 1460, 1461, 2613, 2591, 2590, 1462, 2592, - 63, 64, 3194, 65, 66, 67, 68, 3195, 2595, 3675, - 2596, 3674, 1459, 4000, 1460, 1461, 3558, 3559, 3560, 1902, - 1903, 1904, 2598, 2777, 3192, 3884, 2771, 1727, 1459, 3193, - 1460, 1461, 2566, 2567, 2358, 2347, 1459, 2569, 1460, 1461, - 2748, 1727, 730, 1042, 3510, 3150, 2570, 1462, 2647, 3149, - 2765, 3962, 2740, 1727, 3688, 2809, 3690, 2131, 1462, 3673, - 3162, 3164, 2731, 1727, 60, 3196, 1462, 2860, 2861, 3165, - 2729, 1727, 3495, 3498, 1028, 2102, 3159, 2100, 2812, 1459, - 3494, 1460, 1461, 2716, 1727, 1975, 1045, 1012, 3233, 1462, - 2890, 2911, 1043, 1459, 1046, 1460, 1461, 2848, 2849, 2148, - 1462, 1168, 1167, 101, 2810, 1459, 2385, 1460, 1461, 1028, - 2868, 3329, 2649, 2149, 102, 1459, 2906, 1460, 1461, 2989, - 1426, 2947, 42, 1459, 129, 1460, 1461, 2813, 103, 2815, - 1462, 2865, 2714, 1727, 2867, 3500, 1459, 4172, 1460, 1461, - 2847, 2828, 101, 2712, 1727, 3252, 1462, 2071, 2561, 103, - 1462, 2710, 1727, 102, 89, 2123, 2112, 2113, 2114, 2115, - 2125, 2116, 2117, 2118, 2130, 2126, 2119, 2120, 2127, 2128, - 2129, 2121, 2122, 2124, 2708, 1727, 2369, 2370, 4079, 1699, - 2837, 1462, 2800, 3981, 3878, 1459, 1727, 1460, 1461, 1462, - 3232, 2864, 2353, 2866, 1053, 1054, 1459, 3148, 1460, 1461, - 110, 2550, 2893, 2895, 1459, 3147, 1460, 1461, 1744, 2549, - 2820, 109, 1693, 108, 2870, 2706, 1727, 2548, 2886, 2840, - 2547, 2825, 103, 2945, 2546, 2545, 1462, 1459, 3478, 1460, - 1461, 2704, 1727, 2584, 108, 2702, 1727, 3947, 1459, 1462, - 1460, 1461, 2874, 110, 3946, 3926, 3696, 2877, 2450, 3694, - 3693, 1462, 3686, 3567, 109, 2884, 108, 2887, 1462, 3499, - 2956, 3497, 3265, 1462, 94, 2485, 2700, 1727, 1459, 1462, - 1460, 1461, 1848, 1052, 1743, 2898, 2143, 2909, 110, 3488, - 109, 2144, 2912, 2913, 1459, 3685, 1460, 1461, 1459, 109, - 1460, 1461, 2843, 2908, 4160, 4159, 3, 3659, 2824, 3051, - 2639, 1462, 2339, 2916, 1756, 2917, 1748, 4159, 2921, 2922, - 2923, 2698, 1727, 114, 115, 2953, 4160, 2204, 3968, 1459, - 1462, 1460, 1461, 1853, 2696, 1727, 3533, 1459, 2043, 1460, - 1461, 10, 97, 1, 2942, 2943, 2694, 1727, 1462, 2041, - 1020, 1429, 9, 2692, 1727, 1462, 2999, 3000, 2690, 1727, - 2042, 2952, 1462, 8, 2688, 1727, 1428, 3537, 1462, 4091, - 685, 2329, 1462, 1697, 1459, 4131, 1460, 1461, 1462, 4087, - 4088, 70, 1945, 1935, 3599, 2255, 3879, 1459, 3268, 1460, - 1461, 2981, 3016, 1462, 2997, 2978, 2686, 1727, 1462, 1459, - 2491, 1460, 1461, 3565, 1462, 2448, 1459, 2287, 1460, 1461, - 1120, 1459, 154, 1460, 1461, 2684, 1727, 1459, 2407, 1460, - 1461, 1462, 3034, 3035, 3036, 3037, 3038, 3039, 3040, 3041, - 3042, 3043, 2408, 2682, 1727, 1462, 4056, 2319, 118, 1078, - 2677, 1727, 117, 1123, 2954, 1231, 3017, 2673, 1727, 1459, - 2486, 1460, 1461, 2671, 1727, 1728, 2326, 2664, 1727, 3589, - 2891, 2416, 1781, 2662, 1727, 1779, 1780, 1778, 1459, 1783, - 1460, 1461, 1782, 4028, 2856, 2859, 2860, 2861, 2857, 1727, - 2858, 2862, 3337, 2640, 4137, 3434, 1459, 2034, 1460, 1461, - 3980, 2351, 720, 1459, 3053, 1460, 1461, 3109, 2863, 714, - 1459, 2987, 1460, 1461, 2988, 192, 1459, 3855, 1460, 1461, - 1459, 1770, 1460, 1461, 1749, 1462, 1459, 1162, 1460, 1461, - 1694, 3571, 675, 3241, 2998, 2524, 681, 1511, 2025, 3001, - 1462, 1459, 3146, 1460, 1461, 1462, 1459, 3018, 1460, 1461, - 2878, 3116, 1459, 1072, 1460, 1461, 1064, 2340, 2814, 3127, - 1071, 2932, 3118, 3856, 3180, 2385, 3492, 3158, 3044, 1459, - 3160, 1460, 1461, 2830, 3163, 2198, 3089, 2292, 2290, 2292, - 2290, 3156, 1462, 1459, 3961, 1460, 1461, 3179, 3687, 87, - 2387, 4041, 2385, 2385, 2385, 2385, 2385, 2888, 1745, 3454, - 3099, 3100, 3101, 3102, 3103, 2612, 2138, 2462, 1462, 1501, - 3471, 2384, 2385, 3654, 1031, 2385, 2061, 2387, 2387, 2387, - 2387, 2387, 3127, 743, 3117, 3467, 3119, 3184, 1462, 742, - 3433, 1986, 1462, 740, 2816, 2844, 1462, 2387, 1465, 3201, - 2387, 3126, 949, 2804, 1757, 1462, 3139, 3141, 3143, 2855, - 3144, 1462, 3154, 3138, 2853, 2281, 2282, 2283, 2284, 2285, - 3153, 2852, 3151, 1459, 2559, 1460, 1461, 3429, 2392, 3166, - 3167, 3518, 2306, 1462, 3514, 2309, 2310, 4083, 1459, 3285, - 1460, 1461, 1462, 1459, 1033, 1460, 1461, 2386, 2382, 3293, - 3183, 3186, 3187, 3366, 3189, 1032, 3197, 2823, 104, 3203, - 105, 3185, 3204, 1462, 3188, 900, 899, 3205, 1462, 752, - 744, 2327, 1462, 3365, 734, 3211, 1462, 3357, 962, 898, - 1459, 3355, 1460, 1461, 897, 3295, 3296, 3242, 2962, 3244, - 3243, 2902, 3310, 2964, 2889, 3306, 2794, 3152, 1443, 1716, - 1719, 2348, 1091, 3334, 3987, 2583, 1459, 1462, 1460, 1461, - 3363, 1715, 3245, 3246, 3294, 3994, 3266, 3297, 2793, 3276, - 2450, 3298, 3287, 3583, 3169, 3257, 1459, 2789, 1460, 1461, - 1459, 3304, 1460, 1461, 1459, 2938, 1460, 1461, 2478, 69, - 46, 1462, 3175, 1459, 3956, 1460, 1461, 3175, 2788, 1459, - 4025, 1460, 1461, 2787, 892, 3322, 889, 2786, 3325, 3324, - 3656, 2785, 3657, 3658, 3112, 3113, 3332, 4007, 1462, 4008, - 888, 1459, 4009, 1460, 1461, 2193, 1439, 3342, 3339, 3340, - 1459, 3341, 1460, 1461, 3343, 1436, 3345, 4104, 3347, 2036, - 96, 1462, 2784, 36, 35, 34, 3358, 3359, 3360, 3361, - 3362, 1459, 33, 1460, 1461, 32, 1459, 26, 1460, 1461, - 1459, 25, 1460, 1461, 1459, 24, 1460, 1461, 23, 22, - 29, 1514, 1725, 1721, 19, 1514, 2775, 21, 20, 18, - 3279, 4126, 4171, 3267, 123, 55, 52, 1722, 2599, 50, - 131, 3479, 2604, 3481, 130, 1459, 53, 1460, 1461, 49, - 1205, 47, 31, 2774, 3449, 30, 17, 16, 15, 14, - 13, 3453, 2345, 2346, 1724, 2607, 1723, 2608, 12, 11, - 1725, 1721, 7, 2616, 6, 39, 2773, 2618, 2619, 1459, - 38, 1460, 1461, 37, 28, 1722, 2625, 2626, 2627, 2628, - 2629, 2630, 2631, 2632, 2633, 2634, 3333, 2636, 27, 3178, - 40, 4, 2925, 2385, 2480, 3480, 1459, 3482, 1460, 1461, - 1717, 1718, 1724, 3484, 1723, 0, 3531, 3489, 0, 0, - 2642, 2643, 2644, 2645, 2646, 3496, 2648, 0, 2387, 1459, - 2650, 1460, 1461, 1462, 2655, 2656, 3501, 2657, 0, 0, - 2660, 2661, 2663, 2665, 2666, 2667, 2668, 2669, 2670, 2672, - 2674, 2675, 2676, 2678, 732, 2680, 2681, 2683, 2685, 2687, - 2689, 2691, 2693, 2695, 2697, 2699, 2701, 2703, 2705, 2707, - 2709, 2711, 2713, 2715, 2717, 2718, 2719, 3288, 2721, 3523, - 2723, 3294, 2725, 2726, 3297, 2728, 2730, 2732, 3298, 3532, - 3526, 2735, 3525, 3520, 0, 2739, 3548, 1462, 3550, 2744, - 2745, 2746, 2747, 0, 3327, 3328, 1462, 0, 3593, 3594, - 1462, 0, 2758, 2759, 2760, 2761, 2762, 2763, 2772, 1462, - 2767, 2768, 3456, 1462, 3458, 3459, 3460, 3486, 2770, 1462, - 0, 3542, 3543, 2776, 1462, 0, 0, 0, 2779, 2780, - 2781, 2782, 2783, 0, 1462, 0, 0, 0, 0, 2790, - 2791, 0, 2792, 0, 0, 2795, 2797, 2351, 1462, 2799, - 3513, 0, 0, 1051, 1462, 0, 1057, 1057, 0, 2811, - 0, 1459, 0, 1460, 1461, 0, 0, 1462, 0, 3527, - 3528, 1462, 2769, 0, 3576, 0, 3595, 0, 3580, 3581, - 3582, 2764, 1462, 0, 0, 2757, 0, 0, 0, 0, - 0, 0, 3611, 0, 2756, 0, 0, 0, 2755, 0, - 0, 0, 0, 0, 2754, 1462, 0, 0, 0, 2753, - 0, 0, 0, 2620, 0, 1462, 0, 0, 0, 2752, - 0, 1462, 0, 0, 0, 1459, 0, 1460, 1461, 1462, - 2635, 0, 0, 2751, 1459, 0, 1460, 1461, 1459, 2750, - 1460, 1461, 1462, 0, 0, 0, 1462, 1459, 0, 1460, - 1461, 1459, 2749, 1460, 1461, 0, 2743, 1459, 0, 1460, - 1461, 0, 1459, 0, 1460, 1461, 1462, 2742, 3672, 0, - 0, 3679, 1459, 3681, 1460, 1461, 0, 3662, 1462, 3663, - 3664, 3665, 0, 1462, 0, 3652, 1459, 0, 1460, 1461, - 2741, 0, 1459, 1462, 1460, 1461, 3179, 0, 0, 87, - 2738, 3179, 0, 3682, 0, 1459, 2737, 1460, 1461, 1459, - 1462, 1460, 1461, 0, 2736, 1462, 0, 0, 0, 0, - 1459, 0, 1460, 1461, 42, 1462, 0, 2734, 0, 1462, - 2102, 2727, 2100, 3712, 3683, 3616, 0, 0, 0, 3692, - 3691, 0, 3704, 1459, 3702, 1460, 1461, 0, 3699, 0, - 3701, 2724, 0, 1459, 0, 1460, 1461, 0, 0, 1459, - 0, 1460, 1461, 2722, 0, 0, 3862, 1459, 2720, 1460, - 1461, 0, 0, 0, 0, 0, 0, 3716, 2679, 0, - 1459, 0, 1460, 1461, 1459, 0, 1460, 1461, 0, 0, - 3572, 3573, 0, 0, 0, 2659, 0, 0, 0, 0, - 2658, 0, 0, 0, 1459, 0, 1460, 1461, 3854, 3853, - 2654, 0, 0, 0, 2652, 0, 1459, 0, 1460, 1461, - 3869, 1459, 0, 1460, 1461, 0, 3873, 3874, 0, 3881, - 0, 1459, 3852, 1460, 1461, 0, 0, 0, 3920, 3921, - 0, 0, 3029, 3030, 3031, 3032, 3033, 3706, 1459, 0, - 1460, 1461, 0, 1459, 3680, 1460, 1461, 2102, 0, 2100, - 3924, 0, 3048, 1459, 0, 1460, 1461, 1459, 0, 1460, - 1461, 0, 0, 3864, 3865, 3866, 2856, 2859, 2860, 2861, - 2857, 0, 2858, 2862, 0, 0, 3516, 3517, 0, 3175, - 0, 3713, 3714, 3969, 3179, 0, 3708, 0, 3927, 0, - 0, 0, 3930, 0, 0, 0, 0, 0, 1532, 1533, - 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, - 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1552, 1553, 1554, - 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, - 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, - 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, - 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, - 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, - 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, - 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, - 1625, 1626, 1627, 1629, 1630, 1631, 1632, 1633, 1634, 1635, - 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1650, - 1651, 1652, 1653, 1667, 1668, 1669, 1670, 1671, 1672, 1673, - 1674, 1675, 1676, 1677, 1678, 1679, 1680, 3925, 3954, 3953, - 3970, 0, 0, 1462, 0, 3944, 0, 1462, 3178, 0, - 0, 3988, 3950, 3178, 3952, 0, 0, 0, 1462, 0, - 0, 0, 0, 0, 0, 1700, 0, 0, 0, 87, - 3181, 0, 3019, 0, 0, 0, 0, 3972, 0, 0, - 3973, 0, 0, 0, 0, 0, 0, 0, 3199, 0, - 0, 0, 0, 0, 42, 3857, 3977, 0, 0, 0, - 3993, 0, 3990, 0, 0, 4124, 0, 0, 0, 0, - 0, 0, 3995, 0, 0, 1798, 0, 0, 3861, 0, - 0, 0, 0, 0, 667, 0, 0, 0, 2617, 0, - 0, 0, 2611, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2606, 1015, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4013, 0, 0, 4014, 0, 0, 0, 4038, 0, 0, - 0, 0, 87, 0, 0, 0, 0, 0, 1463, 0, - 0, 1459, 4023, 1460, 1461, 1459, 1086, 1460, 1461, 0, - 0, 0, 0, 0, 0, 4032, 1459, 42, 1460, 1461, - 0, 0, 3091, 0, 3093, 0, 4044, 0, 4069, 1520, - 0, 0, 0, 0, 4055, 4042, 3331, 4047, 4052, 4049, - 3104, 3105, 3106, 3107, 4048, 0, 4046, 3881, 4058, 4051, - 4050, 0, 0, 0, 0, 0, 3974, 4077, 3348, 3349, - 0, 3350, 3352, 3354, 0, 0, 3178, 0, 0, 0, - 0, 0, 0, 0, 4100, 4090, 4095, 4082, 0, 0, - 0, 4108, 1786, 0, 0, 4069, 0, 0, 4110, 3367, - 4121, 0, 0, 0, 3371, 3372, 3373, 3375, 3376, 3377, - 3378, 3379, 3380, 3381, 3382, 3383, 3384, 3385, 3386, 3387, - 3389, 3391, 3393, 3395, 3397, 3399, 3401, 3403, 3405, 3407, - 3409, 3411, 3413, 3415, 3417, 3419, 3420, 3422, 3423, 3424, - 3426, 4125, 1986, 3428, 4140, 3430, 3431, 3432, 4141, 4151, - 3436, 3437, 3438, 3439, 3440, 3441, 3442, 3443, 3444, 3445, - 3446, 4155, 2102, 4157, 2100, 4154, 4153, 4144, 4150, 3452, - 4120, 4034, 4069, 3457, 0, 4165, 1799, 3461, 3462, 4039, - 3463, 3465, 4173, 3468, 3470, 3175, 3472, 3473, 3474, 3475, - 4181, 4179, 0, 0, 0, 0, 3483, 0, 0, 0, - 0, 0, 0, 0, 3979, 0, 0, 0, 0, 0, - 4190, 4191, 3921, 4189, 1798, 0, 0, 0, 0, 0, - 2102, 0, 2100, 4188, 0, 0, 0, 0, 0, 0, - 0, 3507, 3508, 3986, 0, 3512, 0, 0, 3998, 1812, - 1815, 1816, 1817, 1818, 1819, 1820, 0, 1821, 1822, 1824, - 1825, 1823, 1826, 1827, 1800, 1801, 1802, 1803, 1784, 1785, - 1813, 0, 1787, 0, 1788, 1789, 1790, 1791, 1792, 1793, - 1794, 1795, 1796, 0, 0, 1797, 1804, 1805, 1806, 1807, - 0, 1808, 1809, 1810, 1811, 0, 0, 0, 0, 0, - 0, 0, 4116, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4033, 0, 1747, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3587, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1786, 0, 0, 0, 1835, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 945, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3606, 0, 0, 3610, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3622, 0, 0, 0, 0, 0, 0, 0, - 0, 195, 0, 0, 195, 0, 0, 0, 718, 0, - 0, 0, 0, 724, 0, 1799, 0, 0, 0, 0, - 0, 0, 0, 0, 195, 0, 0, 0, 4138, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 195, 0, 1010, 0, 2294, 1694, 0, 1011, 0, 0, - 0, 0, 0, 0, 0, 0, 3645, 2101, 0, 0, - 0, 1814, 0, 1991, 0, 724, 195, 724, 0, 3653, - 0, 0, 0, 0, 0, 0, 3660, 0, 1812, 1815, - 1816, 1817, 1818, 1819, 1820, 0, 1821, 1822, 1824, 1825, - 1823, 1826, 1827, 1800, 1801, 1802, 1803, 1784, 1785, 1813, - 0, 1787, 0, 1788, 1789, 1790, 1791, 1792, 1793, 1794, - 1795, 1796, 0, 0, 1797, 1804, 1805, 1806, 1807, 0, - 1808, 1809, 1810, 1811, 0, 0, 0, 0, 0, 0, - 1206, 0, 1212, 968, 969, 970, 971, 972, 973, 974, - 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, - 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, - 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, - 1005, 1006, 1007, 1008, 1009, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1435, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3870, 0, 0, 0, 0, - 0, 0, 0, 0, 3877, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3887, 3888, 3889, 0, 3891, 0, - 3892, 3893, 0, 0, 0, 3896, 3897, 3898, 3899, 3900, - 3901, 3902, 3903, 3904, 3905, 3906, 3907, 3908, 3909, 3910, - 3911, 3912, 3913, 3914, 3915, 3916, 3917, 0, 3919, 3922, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3931, 3932, 3933, 3934, 3935, 3937, - 3938, 3940, 3942, 3943, 3945, 3643, 0, 0, 3949, 0, - 0, 0, 3951, 2056, 2057, 2058, 2059, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2069, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1814, 0, 0, 0, 0, 0, 0, 3978, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2108, 2109, 0, 0, 0, 0, 2132, - 0, 0, 2136, 2137, 0, 0, 0, 2142, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, - 2162, 2163, 0, 2165, 0, 0, 0, 2187, 2188, 2189, - 2190, 2191, 2192, 2194, 0, 2199, 0, 2201, 2202, 2203, - 0, 2205, 2206, 2207, 0, 2209, 2210, 2211, 2212, 2213, - 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, - 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, - 2234, 2235, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, - 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, - 2254, 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, - 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, - 2277, 2278, 2279, 2280, 0, 0, 0, 0, 0, 2286, - 0, 2288, 0, 2295, 2296, 2297, 2298, 2299, 2300, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2311, 2312, 2313, 2314, 2315, 2316, 2317, 2318, - 0, 2320, 2321, 2322, 2323, 2324, 1759, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4003, 0, 0, 1776, 0, 0, 0, 0, - 0, 0, 3960, 0, 0, 0, 0, 0, 0, 0, - 0, 1057, 0, 0, 0, 0, 4018, 0, 0, 0, - 0, 0, 4021, 0, 4022, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2365, 2366, - 0, 0, 0, 0, 0, 0, 0, 4037, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 195, 0, 195, 0, 2404, 0, 0, 0, 0, 0, - 0, 0, 0, 4063, 4064, 0, 0, 0, 1915, 0, - 0, 0, 0, 0, 0, 0, 0, 4071, 4073, 4075, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 724, - 0, 724, 724, 0, 0, 4081, 0, 0, 0, 0, - 0, 0, 0, 1960, 0, 0, 0, 4103, 0, 0, - 0, 724, 195, 0, 0, 2446, 0, 0, 0, 0, - 1987, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1998, 0, 0, 0, - 1506, 190, 0, 2002, 0, 4122, 0, 0, 0, 0, - 0, 0, 2931, 0, 2013, 2014, 2015, 2016, 2017, 2018, - 2019, 0, 0, 0, 0, 129, 0, 151, 1694, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 172, 4145, - 4147, 4149, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1010, 0, 0, 0, 162, - 1011, 0, 4170, 0, 0, 150, 0, 0, 0, 0, - 2101, 0, 0, 0, 4002, 0, 0, 0, 0, 0, - 4182, 4183, 4012, 0, 169, 0, 0, 170, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1856, 1857, 161, - 160, 189, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1694, 0, 968, 969, 970, 971, - 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, - 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, - 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, - 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 0, 0, - 0, 1506, 0, 0, 0, 0, 0, 0, 0, 0, - 2049, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 155, 1858, 158, 0, 1855, 0, 156, 157, - 0, 0, 0, 0, 0, 173, 0, 0, 0, 0, - 0, 0, 0, 0, 179, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, - 0, 0, 0, 724, 724, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 195, 0, 0, 2615, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2621, 2622, 2623, 2624, 0, - 0, 0, 0, 724, 0, 0, 195, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 724, 0, - 0, 0, 0, 0, 0, 195, 0, 0, 0, 724, - 0, 0, 0, 0, 0, 0, 0, 0, 1520, 724, + 962, 3656, 3657, 87, 3655, 950, 4074, 4183, 4093, 4170, + 3984, 3221, 3321, 3966, 2117, 4137, 1273, 957, 3606, 949, + 2105, 4062, 4138, 3228, 2339, 3270, 3456, 2411, 3889, 3279, + 3182, 3284, 3281, 3964, 3037, 3280, 3278, 1271, 3283, 1780, + 3593, 3282, 2341, 3299, 3120, 2485, 1987, 3236, 3298, 743, + 2043, 3186, 3183, 5, 3502, 1736, 3698, 3011, 3180, 3496, + 2838, 2366, 737, 3301, 3170, 3036, 2448, 738, 3486, 2912, + 3328, 1836, 911, 2993, 771, 2944, 4035, 910, 2473, 2453, + 2913, 915, 2914, 2399, 42, 2516, 1030, 2382, 87, 163, + 2387, 2385, 1050, 1082, 1027, 1883, 2386, 1057, 2863, 2814, + 2830, 41, 1128, 43, 2295, 1152, 2263, 1030, 3524, 2139, + 2101, 2985, 2494, 149, 2051, 2262, 2472, 2374, 1865, 2533, + 2455, 2905, 1092, 1115, 1110, 2851, 1769, 2880, 1749, 1522, + 100, 2844, 2389, 1701, 2145, 104, 2076, 105, 2065, 1447, + 1432, 1872, 1983, 1089, 1086, 1964, 2470, 753, 1121, 3185, + 1090, 2444, 2445, 1116, 1117, 1768, 748, 1039, 1067, 1069, + 1118, 1754, 1723, 2153, 3693, 2172, 2812, 1029, 99, 1033, + 1505, 1481, 1036, 107, 2042, 85, 1261, 1995, 167, 1049, + 127, 125, 3685, 126, 2367, 3457, 1857, 3513, 1052, 1034, + 912, 1035, 1025, 132, 133, 1201, 1062, 747, 1037, 741, + 1526, 740, 98, 4171, 93, 1247, 1269, 2487, 2488, 2489, + 1061, 3594, 84, 3267, 2487, 1531, 4019, 2967, 2966, 106, + 2935, 2531, 1024, 3586, 3549, 4120, 730, 3001, 3002, 4015, + 1042, 128, 2336, 2337, 4014, 2058, 2057, 2056, 2055, 1132, + 134, 2054, 4020, 1083, 1157, 2053, 675, 2026, 1217, 672, + 1218, 673, 4114, 2810, 2581, 3166, 4141, 1154, 2520, 3124, + 3660, 1165, 4193, 3660, 4136, 4161, 3460, 2363, 3459, 1043, + 1171, 1172, 1173, 1076, 1176, 1177, 1178, 1179, 2, 2362, + 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1131, 1028, 731, + 95, 1077, 2519, 128, 1026, 1106, 1105, 95, 1104, 3993, + 1464, 1051, 1740, 1107, 2960, 2937, 1158, 1161, 1162, 2840, + 1730, 3289, 3967, 111, 112, 113, 2079, 116, 1099, 1443, + 122, 3289, 1949, 191, 1738, 4015, 667, 1094, 3347, 2360, + 95, 2775, 1741, 709, 3286, 4176, 715, 1023, 728, 729, + 3659, 190, 1174, 3659, 2063, 4089, 4124, 4122, 1018, 1019, + 1020, 1021, 916, 715, 1739, 1032, 1075, 1079, 914, 2957, + 4175, 128, 190, 95, 129, 3885, 3884, 3287, 1075, 1079, + 914, 4123, 4121, 3599, 1156, 1108, 3600, 3287, 1155, 4151, + 172, 3895, 4118, 1064, 1065, 129, 1434, 965, 966, 967, + 965, 966, 967, 3618, 3293, 86, 3607, 1460, 2588, 709, + 4063, 172, 709, 86, 3293, 4071, 2513, 3894, 2110, 86, + 4098, 3373, 1846, 2889, 709, 1770, 2888, 1771, 2854, 2890, + 3218, 3219, 2811, 2894, 2406, 2407, 2035, 2036, 3217, 3000, + 2585, 2405, 1254, 2984, 1256, 1237, 169, 1016, 4075, 170, + 2518, 1461, 706, 1462, 1463, 1015, 2855, 1266, 4103, 1098, + 1242, 1243, 1100, 1225, 3712, 3617, 1225, 169, 1226, 2938, + 170, 1226, 3985, 189, 1238, 2586, 4101, 1231, 2901, 1224, + 1991, 1223, 1253, 1255, 709, 95, 4107, 4108, 3325, 3998, + 2424, 2423, 709, 95, 189, 3238, 3239, 3323, 709, 95, + 691, 3355, 4102, 2847, 2848, 2338, 1103, 3353, 1210, 1211, + 4142, 2579, 86, 689, 709, 88, 2034, 1482, 3290, 1766, + 1200, 723, 2181, 721, 4079, 2038, 1175, 4079, 3290, 3058, + 727, 4143, 1444, 3329, 1705, 2370, 2986, 2495, 1939, 3344, + 1213, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1491, 1490, + 1492, 1493, 3937, 686, 3938, 710, 2534, 2370, 2538, 1433, + 2945, 1103, 701, 1095, 1101, 1244, 3316, 1265, 2970, 1239, + 1097, 1096, 1232, 1264, 3317, 1245, 2540, 696, 2582, 1263, + 2583, 3326, 1940, 4173, 1941, 1258, 1965, 173, 699, 1251, + 3324, 3588, 95, 1252, 1068, 1246, 179, 1240, 1241, 2464, + 2537, 1206, 2988, 1257, 3237, 3587, 2536, 2560, 173, 1181, + 2974, 2975, 1180, 2539, 3869, 3584, 3240, 179, 1992, 1101, + 2173, 710, 2458, 1111, 710, 2175, 1708, 1112, 1250, 2180, + 2176, 2541, 3240, 2177, 2178, 2179, 710, 2498, 2174, 2182, + 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, 2557, 3664, + 2558, 4115, 2559, 2383, 1496, 1112, 676, 1150, 678, 692, + 1149, 712, 1148, 711, 682, 1147, 680, 684, 693, 685, + 3123, 679, 1146, 690, 1145, 1850, 681, 694, 695, 698, + 702, 703, 704, 700, 697, 3499, 688, 713, 1078, 1072, + 1070, 1144, 1143, 1102, 1138, 3059, 710, 1151, 1087, 4194, + 1078, 1072, 1070, 1124, 710, 4148, 1270, 1087, 1270, 1270, + 710, 2547, 2543, 2545, 2546, 2544, 2548, 2549, 2550, 1087, + 1123, 164, 1984, 1085, 2471, 1160, 710, 1063, 2368, 2369, + 3583, 1123, 2989, 2524, 2523, 1159, 1980, 1435, 1168, 3260, + 3005, 2969, 164, 1844, 1843, 1842, 4116, 1767, 1102, 2955, + 2368, 2369, 1981, 1840, 1216, 666, 1030, 1506, 1511, 1512, + 3980, 1515, 1517, 1518, 1519, 1520, 1521, 2939, 1524, 1525, + 1527, 1527, 2457, 1527, 1527, 1532, 1532, 1532, 1535, 1536, + 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, + 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, + 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, + 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, + 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, + 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, + 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, + 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, + 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, + 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, + 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, + 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, + 4038, 1259, 1448, 1503, 1657, 3992, 1659, 1660, 1661, 1662, + 1663, 2936, 3547, 3548, 1426, 1427, 1109, 963, 1532, 1532, + 1532, 1532, 1532, 1532, 963, 3658, 2517, 1221, 3658, 1227, + 1228, 1229, 1230, 1670, 1671, 1672, 1673, 1674, 1675, 1676, + 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1507, 1425, 1499, + 1500, 1501, 1502, 1267, 1268, 1448, 3345, 963, 2972, 1513, + 165, 1141, 714, 1516, 1698, 1071, 2903, 177, 2587, 2959, + 3616, 1528, 4077, 1529, 1530, 4077, 89, 1071, 1139, 94, + 1496, 165, 1442, 707, 3444, 3500, 4106, 94, 177, 3291, + 3292, 1533, 1534, 94, 1130, 1204, 1212, 1222, 708, 3291, + 3292, 1970, 3295, 3012, 4076, 1209, 2586, 4076, 185, 2992, + 1458, 2515, 3295, 2958, 1871, 1969, 2983, 1130, 1704, 2982, + 1951, 1950, 1952, 1953, 1954, 3132, 1130, 1030, 3538, 185, + 4105, 1030, 1497, 1498, 1729, 3224, 3520, 1030, 2885, 2815, + 2817, 2850, 2787, 1235, 1695, 2113, 1758, 124, 1658, 1215, + 3131, 166, 171, 168, 174, 175, 176, 178, 180, 181, + 182, 183, 2845, 1458, 1696, 674, 2603, 184, 186, 187, + 188, 1167, 166, 171, 168, 174, 175, 176, 178, 180, + 181, 182, 183, 3225, 2412, 1496, 94, 3014, 184, 186, + 187, 188, 1493, 3216, 2614, 1476, 1046, 1129, 1262, 2081, + 1730, 4006, 2461, 4187, 1248, 3032, 1996, 3227, 1712, 1153, + 1142, 3579, 1716, 2082, 1494, 1495, 2080, 2146, 1029, 1454, + 1129, 119, 1714, 1870, 1715, 3222, 104, 1140, 105, 1129, + 2154, 1220, 1696, 1664, 1665, 1666, 1667, 1668, 1669, 3512, + 2535, 1464, 2047, 2462, 3238, 3239, 1977, 2155, 1702, 1772, + 2460, 3223, 2928, 1103, 1199, 1689, 4152, 1130, 3024, 3023, + 3022, 3151, 3707, 3016, 107, 3020, 1966, 3015, 1967, 3013, + 3149, 1968, 1454, 2995, 3018, 1446, 2995, 2146, 2994, 2623, + 2614, 2994, 1463, 3017, 2463, 3229, 1464, 1130, 1488, 1489, + 1491, 1490, 1492, 1493, 2459, 120, 1130, 1462, 1463, 3554, + 3553, 3019, 3021, 1732, 1464, 1710, 2502, 1880, 1130, 2816, + 1879, 2514, 1863, 1847, 1848, 1849, 1869, 1973, 1203, 1971, + 1972, 1713, 1974, 1975, 1976, 3362, 2512, 1934, 1856, 1873, + 1873, 1711, 1989, 1130, 1885, 2510, 1886, 1735, 1888, 1890, + 1205, 1699, 1894, 1896, 1898, 1900, 1902, 1875, 1026, 1028, + 1801, 1141, 1234, 3237, 2507, 1249, 1916, 1997, 1270, 2137, + 1129, 1763, 1764, 1236, 2140, 3240, 1123, 1126, 1127, 1874, + 1087, 1831, 2507, 1139, 1120, 1124, 4144, 4039, 1219, 2152, + 1924, 1925, 1461, 3539, 1462, 1463, 1930, 1931, 1041, 1839, + 1129, 3034, 1166, 1730, 2511, 1119, 1163, 1464, 4195, 1129, + 1853, 965, 966, 967, 1133, 1123, 1866, 1854, 1852, 1135, + 1717, 1129, 2509, 1136, 1134, 4189, 715, 1123, 1126, 1127, + 3877, 1087, 1877, 4040, 1202, 1120, 1124, 1461, 4185, 1462, + 1463, 4186, 3876, 4184, 1137, 3972, 1129, 3867, 3630, 733, + 1102, 1133, 1123, 1959, 1464, 1461, 1135, 1462, 1463, 1912, + 1136, 1134, 1915, 1920, 1917, 1985, 3629, 2129, 2118, 2119, + 2120, 2121, 2131, 2122, 2123, 2124, 2136, 2132, 2125, 2126, + 2133, 2134, 2135, 2127, 2128, 2130, 3561, 3613, 1845, 3614, + 3560, 3973, 3226, 2300, 128, 3899, 1106, 1105, 4196, 1104, + 1484, 1485, 1486, 1487, 1488, 1489, 1491, 1490, 1492, 1493, + 1789, 1486, 1487, 1488, 1489, 1491, 1490, 1492, 1493, 3550, + 1958, 2002, 1957, 1946, 3268, 1453, 1450, 1451, 1452, 1457, + 1459, 1456, 2612, 1455, 1730, 1270, 1270, 3256, 2910, 1998, + 1999, 2151, 2611, 1449, 2909, 2024, 2908, 2467, 1461, 87, + 1462, 1463, 87, 2003, 2069, 2070, 2593, 2594, 1960, 1944, + 2010, 2011, 2012, 1483, 1484, 1485, 1486, 1487, 1488, 1489, + 1491, 1490, 1492, 1493, 2023, 1464, 3544, 715, 1453, 1450, + 1451, 1452, 1457, 1459, 1456, 1482, 1455, 3004, 2658, 1956, + 1945, 1943, 2000, 1942, 1802, 1461, 1449, 1462, 1463, 2004, + 1932, 2006, 2007, 2008, 2009, 1926, 1923, 1922, 2013, 1483, + 1484, 1485, 1486, 1487, 1488, 1489, 1491, 1490, 1492, 1493, + 2025, 1921, 1482, 1892, 1709, 2108, 2108, 2106, 2106, 2109, + 42, 3320, 1429, 42, 1470, 1471, 1472, 1473, 1474, 1475, + 1469, 1466, 2892, 715, 2662, 2071, 1483, 1484, 1485, 1486, + 1487, 1488, 1489, 1491, 1490, 1492, 1493, 1815, 1818, 1819, + 1820, 1821, 1822, 1823, 1730, 1824, 1825, 1827, 1828, 1826, + 1829, 1830, 1803, 1804, 1805, 1806, 1787, 1788, 1816, 2192, + 1790, 1766, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, + 1799, 2836, 4172, 1800, 1807, 1808, 1809, 1810, 101, 1811, + 1812, 1813, 1814, 4145, 2069, 2070, 2067, 2068, 102, 1695, + 4001, 1464, 2483, 2482, 2481, 2480, 1461, 4000, 1462, 1463, + 1464, 85, 2479, 2478, 85, 1482, 2048, 2602, 1464, 1696, + 2066, 3976, 1743, 3975, 3230, 2078, 2375, 2376, 3234, 2141, + 3974, 2031, 2032, 1482, 3872, 3233, 1478, 1464, 1479, 1483, + 1484, 1485, 1486, 1487, 1488, 1489, 1491, 1490, 1492, 1493, + 2083, 1464, 1480, 1494, 1495, 1477, 1730, 1483, 1484, 1485, + 1486, 1487, 1488, 1489, 1491, 1490, 1492, 1493, 1744, 3235, + 4132, 1730, 2836, 1730, 3231, 2310, 3856, 2112, 3855, 3232, + 2085, 2084, 2214, 2086, 2087, 2088, 2089, 2090, 2091, 2093, + 2095, 2096, 2097, 2098, 2099, 2100, 2308, 1507, 4157, 1730, + 2156, 2157, 2158, 2159, 1482, 2309, 4155, 1730, 1460, 1730, + 2660, 2836, 4070, 2298, 2170, 2147, 2836, 4049, 1730, 2191, + 1460, 1730, 3994, 2296, 3706, 4085, 1730, 1464, 1483, 1484, + 1485, 1486, 1487, 1488, 1489, 1491, 1490, 1492, 1493, 4083, + 1730, 3904, 1461, 1464, 1462, 1463, 2836, 4045, 3903, 3957, + 1730, 1461, 2300, 1462, 1463, 1464, 2297, 3597, 3991, 1461, + 1464, 1462, 1463, 110, 2391, 2299, 2206, 2307, 3880, 1730, + 2313, 2314, 2836, 3868, 109, 2310, 108, 1464, 1461, 961, + 1462, 1463, 3704, 3626, 103, 1464, 1694, 1693, 104, 1692, + 105, 3558, 1461, 1464, 1462, 1463, 2308, 3597, 1730, 1817, + 1464, 2836, 3595, 3511, 3543, 2380, 2507, 1730, 2421, 104, + 3330, 105, 3518, 1730, 2343, 4081, 1730, 2355, 1464, 2742, + 1730, 3860, 1464, 101, 3327, 3259, 1464, 3258, 2919, 103, + 2906, 3950, 1730, 102, 3249, 3248, 1092, 3246, 3247, 3859, + 2077, 3244, 3245, 3948, 1730, 2393, 1730, 3515, 3945, 1730, + 3244, 3243, 3605, 2430, 2431, 2432, 2433, 2425, 1464, 2426, + 2427, 2428, 2429, 1042, 1464, 2331, 1730, 2415, 1461, 1092, + 1462, 1463, 2416, 3927, 1730, 2436, 2437, 2438, 2439, 2397, + 1691, 3485, 1730, 1464, 1461, 2356, 1462, 1463, 3478, 1730, + 2946, 1730, 2358, 2349, 1684, 2350, 1461, 2450, 1462, 1463, + 2570, 1461, 2419, 1462, 1463, 2569, 3475, 1730, 2496, 1464, + 3473, 1730, 3514, 2456, 3436, 1730, 2924, 2378, 1461, 2529, + 1462, 1463, 1076, 2403, 2402, 2401, 1461, 110, 1462, 1463, + 2860, 1730, 2418, 2417, 1461, 2528, 1462, 1463, 109, 2881, + 108, 1461, 2365, 1462, 1463, 1464, 3434, 1730, 2586, 2968, + 1077, 2344, 3430, 1730, 2466, 1464, 2493, 1835, 2949, 1461, + 1464, 1462, 1463, 1461, 1132, 1462, 1463, 1461, 103, 1462, + 1463, 3427, 1730, 1464, 1873, 2027, 2451, 2440, 2442, 2443, + 2447, 2942, 2943, 2836, 2835, 2469, 2465, 1993, 2501, 1955, + 1464, 2504, 2477, 2505, 1464, 2111, 1730, 3425, 1730, 1461, + 1947, 1462, 1463, 1464, 2882, 1461, 2881, 1462, 1463, 2521, + 1730, 2451, 2500, 2503, 2884, 2499, 2852, 1937, 1464, 1933, + 1929, 1928, 1131, 1927, 1461, 1464, 1462, 1463, 1745, 2522, + 1730, 2525, 1464, 3423, 1730, 2526, 2527, 1464, 2619, 1260, + 2833, 1835, 1834, 3421, 1730, 1778, 1777, 3181, 3419, 1730, + 1461, 1464, 1462, 1463, 103, 2852, 1464, 3211, 3511, 1460, + 1464, 3417, 1730, 2420, 2591, 1464, 4033, 2586, 4005, 1731, + 1733, 2882, 2836, 1030, 1030, 1030, 2860, 2532, 3415, 1730, + 2508, 2586, 3413, 1730, 109, 3464, 1461, 3246, 1462, 1463, + 2860, 3411, 1730, 1517, 1464, 1517, 1461, 3154, 1462, 1463, + 2859, 1461, 1464, 1462, 1463, 2404, 3409, 1730, 2742, 2647, + 2646, 2606, 2507, 2618, 1461, 2831, 1462, 1463, 2490, 2373, + 3407, 1730, 1734, 1464, 2563, 3405, 1730, 1464, 2334, 3511, + 2310, 1461, 3562, 1462, 1463, 1461, 2111, 1462, 1463, 3403, + 1730, 2507, 2049, 1464, 1461, 4146, 1462, 1463, 3401, 1730, + 2033, 2609, 1979, 3399, 1730, 1460, 1765, 1114, 2860, 1461, + 2309, 1462, 1463, 1464, 1031, 1113, 1461, 1464, 1462, 1463, + 1908, 1464, 95, 1461, 2578, 1462, 1463, 4111, 1461, 1464, + 1462, 1463, 3397, 1730, 4052, 3891, 3563, 3564, 3565, 2584, + 3383, 1730, 1461, 1737, 1462, 1463, 3857, 1461, 3719, 1462, + 1463, 1461, 2650, 1462, 1463, 2592, 1461, 3578, 1462, 1463, + 1464, 3360, 1730, 3575, 1464, 2807, 1730, 2598, 3556, 3378, + 2595, 2596, 2597, 3377, 1909, 1910, 1911, 1697, 2078, 1837, + 2915, 2805, 1730, 2449, 3318, 1461, 3273, 1462, 1463, 3269, + 2950, 2446, 2441, 1461, 95, 1462, 1463, 1464, 2435, 2572, + 2573, 2780, 1730, 2434, 2575, 2757, 1730, 1464, 3271, 2749, + 1730, 1464, 1962, 2576, 1461, 1868, 1462, 1463, 1461, 1864, + 1462, 1463, 1833, 1464, 121, 3566, 2916, 1204, 3322, 2622, + 3892, 2916, 2600, 2599, 1461, 2601, 1462, 1463, 1904, 3525, + 3526, 1464, 3531, 2464, 2604, 2347, 2605, 1464, 2740, 1730, + 2029, 4167, 2607, 3989, 1461, 1464, 1462, 1463, 1461, 2786, + 1462, 1463, 1461, 4165, 1462, 1463, 4139, 4013, 1464, 3932, + 1461, 3528, 1462, 1463, 1742, 3567, 3568, 3569, 2774, 2656, + 3265, 1464, 3264, 3263, 4009, 2738, 1730, 1464, 1905, 1906, + 1907, 2818, 3181, 1482, 2929, 2725, 1730, 2564, 671, 2723, + 1730, 1461, 3530, 1462, 1463, 1461, 1464, 1462, 1463, 3200, + 1030, 2721, 1730, 2108, 2030, 2106, 2821, 1483, 1484, 1485, + 1486, 1487, 1488, 1489, 1491, 1490, 1492, 1493, 3199, 2719, + 1730, 1464, 3203, 2857, 2858, 2819, 3864, 3204, 1461, 3893, + 1462, 1463, 2391, 2717, 1730, 1030, 2877, 2364, 1461, 1044, + 1462, 1463, 1461, 2353, 1462, 1463, 2715, 1730, 2822, 3205, + 2824, 2869, 2870, 3201, 1461, 3519, 1462, 1463, 3202, 2713, + 1730, 3159, 732, 3158, 3971, 2711, 1730, 2837, 3504, 1464, + 3697, 3699, 1461, 2856, 1462, 1463, 3503, 3507, 1461, 1464, + 1462, 1463, 3168, 2077, 2709, 1730, 1461, 1047, 1462, 1463, + 1045, 3171, 3173, 1464, 1978, 1048, 3684, 1014, 3683, 1461, + 3174, 1462, 1463, 3242, 42, 2899, 1464, 1702, 2809, 2707, + 1730, 1464, 1461, 2874, 1462, 1463, 2876, 1724, 1461, 2556, + 1462, 1463, 2920, 2875, 1056, 2829, 1464, 2555, 2902, 2904, + 2554, 1728, 2553, 1696, 1725, 2154, 1464, 1461, 1055, 1462, + 1463, 2846, 2849, 2552, 2895, 2551, 1747, 2834, 3682, 2954, + 3338, 2879, 2155, 2074, 2072, 2073, 1170, 2705, 1730, 2351, + 2352, 1727, 1461, 1726, 1462, 1463, 2883, 2703, 1730, 101, + 1169, 2886, 2915, 2456, 2998, 1724, 1464, 1428, 2893, 102, + 2896, 2701, 1730, 1464, 2956, 110, 2137, 1464, 129, 1728, + 3509, 103, 1725, 2965, 2699, 1730, 109, 2907, 108, 2697, + 1730, 4181, 2149, 2918, 3261, 2567, 103, 2150, 2921, 2922, + 1461, 4088, 1462, 1463, 1746, 2917, 1464, 1720, 1721, 1727, + 1461, 1726, 1462, 1463, 2695, 1730, 2925, 2375, 2376, 2926, + 3990, 2930, 2931, 2932, 1461, 1464, 1462, 1463, 2962, 108, + 1464, 3887, 3241, 2210, 1856, 1464, 2873, 1461, 2359, 1462, + 1463, 3487, 1461, 2590, 1462, 1463, 3956, 3955, 2610, 3008, + 3009, 2951, 2952, 109, 2693, 1730, 3935, 1461, 3705, 1462, + 1463, 2691, 1730, 3157, 2961, 2686, 1730, 1461, 3694, 1462, + 1463, 3156, 1464, 3703, 2129, 2118, 2119, 2120, 2121, 2131, + 2122, 2123, 2124, 2136, 2132, 2125, 2126, 2133, 2134, 2135, + 2127, 2128, 2130, 1464, 2682, 1730, 2987, 3702, 3695, 3025, + 3006, 3576, 3508, 3506, 1464, 3274, 2491, 1461, 2990, 1462, + 1463, 110, 1851, 2293, 1461, 1464, 1462, 1463, 1461, 3580, + 1462, 1463, 109, 2680, 1730, 1054, 3497, 2852, 4169, 4168, + 3043, 3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, + 3668, 1464, 101, 2325, 2963, 110, 1464, 1461, 103, 1462, + 1463, 2833, 102, 3026, 4168, 1464, 109, 3060, 108, 4169, + 3533, 1731, 2332, 2648, 2345, 1759, 1461, 1751, 1462, 1463, + 3977, 1461, 3542, 1462, 1463, 3, 1461, 97, 1462, 1463, + 1464, 2673, 1730, 1, 1464, 114, 115, 2046, 2044, 1022, + 10, 9, 2671, 1730, 1431, 2045, 1430, 2357, 8, 3546, + 4100, 3062, 687, 3480, 2335, 1700, 3118, 2996, 4140, 4096, + 2997, 4097, 1697, 1461, 1948, 1462, 1463, 1938, 3608, 2261, + 3888, 1464, 3277, 2497, 2865, 2868, 2869, 2870, 2866, 3476, + 2867, 2871, 3574, 3007, 1461, 2911, 1462, 1463, 3010, 2454, + 1122, 154, 3125, 3442, 2413, 1461, 3027, 1462, 1463, 2414, + 4065, 118, 1080, 117, 3127, 3136, 1461, 2204, 1462, 1463, + 1125, 2941, 1233, 2492, 2391, 1464, 3598, 3053, 3438, 2900, + 2422, 2298, 3375, 2298, 1784, 1464, 1782, 1783, 1781, 3098, + 1464, 2296, 1461, 2296, 1462, 1463, 3188, 1461, 87, 1462, + 1463, 2391, 2391, 2391, 2391, 2391, 1461, 1786, 1462, 1463, + 1785, 4037, 3346, 2468, 3108, 3109, 3110, 3111, 3112, 3374, + 2649, 2391, 3443, 3126, 2391, 3128, 2037, 722, 3136, 2872, + 3193, 1461, 716, 1462, 1463, 1461, 3135, 1462, 1463, 1464, + 192, 1773, 1989, 3210, 1752, 1164, 677, 2287, 2288, 2289, + 2290, 2291, 1464, 3147, 3153, 2393, 1464, 3250, 3148, 3150, + 3152, 2530, 1464, 3366, 2312, 3163, 1464, 2315, 2316, 3162, + 3160, 683, 1461, 3364, 1462, 1463, 1464, 1514, 2803, 1033, + 2028, 3155, 2393, 2393, 2393, 2393, 2393, 2887, 3294, 1074, + 1066, 2346, 3195, 3196, 3192, 3198, 3161, 3194, 3302, 1034, + 3197, 1035, 2393, 2333, 2823, 2393, 1073, 104, 3214, 105, + 3206, 3865, 3212, 3175, 3176, 3213, 1461, 3189, 1462, 1463, + 1464, 3501, 3167, 3169, 3220, 1464, 1461, 2802, 1462, 1463, + 2839, 1461, 3172, 1462, 1463, 3253, 3252, 3251, 1464, 3165, + 2798, 3970, 3696, 4050, 2797, 1464, 2897, 1748, 3463, 2621, + 2796, 2144, 1504, 1464, 2795, 2390, 3663, 2064, 745, 744, + 742, 3254, 3255, 1464, 2794, 2825, 2853, 1464, 2456, 3296, + 3306, 3178, 3303, 1468, 1464, 3307, 3275, 3313, 1467, 951, + 1461, 2813, 1462, 1463, 1760, 3184, 2864, 1464, 2862, 2861, + 3184, 2565, 2398, 1461, 3527, 1462, 1463, 1461, 3331, 1462, + 1463, 3334, 3523, 1461, 3333, 1462, 1463, 1461, 2793, 1462, + 1463, 4092, 3341, 2784, 2392, 2388, 2832, 1461, 902, 1462, + 1463, 901, 754, 3351, 3348, 3349, 2783, 3350, 746, 736, + 3352, 964, 3354, 2782, 3356, 900, 899, 3304, 3305, 2971, + 3319, 2781, 2973, 2898, 3367, 3368, 3369, 3370, 3371, 3315, + 1445, 2778, 1719, 1722, 2354, 2773, 1093, 3343, 3996, 2589, + 3372, 1461, 2766, 1462, 1463, 1718, 1461, 4003, 1462, 1463, + 1517, 3285, 3592, 3266, 1517, 2765, 3276, 2947, 2484, 1461, + 69, 1462, 1463, 46, 3965, 4034, 1461, 2608, 1462, 1463, + 3488, 2613, 3490, 894, 1461, 3458, 1462, 1463, 891, 3665, + 3666, 3667, 3462, 3121, 1461, 3122, 1462, 1463, 1461, 4016, + 1462, 1463, 4017, 890, 2616, 1461, 2617, 1462, 1463, 4018, + 2199, 1441, 2625, 1438, 4113, 2039, 2627, 2628, 1461, 96, + 1462, 1463, 36, 35, 34, 2634, 2635, 2636, 2637, 2638, + 2639, 2640, 2641, 2642, 2643, 3342, 2645, 33, 32, 26, + 25, 24, 2391, 23, 22, 29, 19, 3493, 3187, 3489, + 21, 3491, 20, 18, 3288, 3540, 3498, 4135, 1464, 2651, + 2652, 2653, 2654, 2655, 3505, 2657, 4180, 123, 55, 2659, + 1464, 3510, 52, 2664, 2665, 50, 2666, 3336, 3337, 2669, + 2670, 2672, 2674, 2675, 2676, 2677, 2678, 2679, 2681, 2683, + 2684, 2685, 2687, 3532, 2689, 2690, 2692, 2694, 2696, 2698, + 2700, 2702, 2704, 2706, 2708, 2710, 2712, 2714, 2716, 2718, + 2720, 2722, 2724, 2726, 2727, 2728, 3495, 2730, 3541, 2732, + 3297, 2734, 2735, 2393, 2737, 2739, 2741, 3306, 3534, 3303, + 2744, 734, 3307, 3535, 2748, 3557, 3529, 3559, 2753, 2754, + 2755, 2756, 1464, 131, 3602, 3603, 2764, 1464, 130, 3522, + 53, 2767, 2768, 2769, 2770, 2771, 2772, 1464, 2763, 2776, + 2777, 3465, 1464, 3467, 3468, 3469, 49, 2779, 3536, 3537, + 3551, 3552, 2785, 1207, 47, 1464, 31, 2788, 2789, 2790, + 2791, 2792, 1464, 30, 17, 16, 1464, 15, 2799, 2800, + 1464, 2801, 14, 13, 2804, 2806, 2357, 12, 2808, 1461, + 3604, 1462, 1463, 11, 7, 6, 39, 38, 2820, 37, + 28, 1461, 27, 1462, 1463, 40, 1464, 4, 2934, 2486, + 1464, 0, 0, 3585, 0, 0, 0, 3589, 3590, 3591, + 2762, 0, 0, 1464, 0, 2761, 0, 0, 0, 0, + 1053, 3620, 0, 1059, 1059, 2760, 0, 0, 2629, 1464, + 2759, 0, 0, 0, 0, 0, 1464, 0, 0, 0, + 0, 1464, 0, 2758, 0, 2644, 1464, 0, 0, 0, + 2752, 0, 0, 0, 2751, 0, 0, 1464, 2750, 0, + 0, 0, 1464, 1461, 0, 1462, 1463, 1464, 1461, 0, + 1462, 1463, 1464, 0, 0, 0, 0, 0, 1461, 0, + 1462, 1463, 0, 1461, 2747, 1462, 1463, 1464, 2746, 0, + 3671, 0, 3672, 3673, 3674, 0, 1461, 3681, 1462, 1463, + 3688, 2745, 3690, 1461, 1464, 1462, 1463, 1461, 0, 1462, + 1463, 1461, 3661, 1462, 1463, 0, 1464, 2743, 0, 0, + 0, 0, 0, 0, 2736, 3188, 0, 3691, 87, 2733, + 3188, 0, 0, 0, 2731, 0, 0, 1461, 0, 1462, + 1463, 1461, 0, 1462, 1463, 2729, 0, 0, 0, 0, + 2688, 0, 1464, 0, 1461, 2668, 1462, 1463, 0, 0, + 2667, 2108, 3625, 2106, 3721, 3692, 3701, 3700, 3711, 0, + 1461, 0, 1462, 1463, 3708, 2663, 3710, 1461, 3713, 1462, + 1463, 0, 1461, 0, 1462, 1463, 0, 1461, 0, 1462, + 1463, 0, 2661, 0, 0, 3871, 0, 0, 1461, 0, + 1462, 1463, 3725, 1461, 2626, 1462, 1463, 0, 1461, 42, + 1462, 1463, 0, 1461, 0, 1462, 1463, 0, 0, 0, + 0, 0, 0, 3581, 3582, 0, 0, 0, 1461, 0, + 1462, 1463, 3863, 0, 3862, 0, 3861, 0, 0, 0, + 2620, 0, 0, 0, 3878, 1461, 0, 1462, 1463, 0, + 0, 3883, 0, 3882, 0, 3890, 0, 1461, 0, 1462, + 1463, 0, 0, 0, 0, 0, 0, 3929, 3930, 0, + 3722, 3723, 0, 0, 3038, 3039, 3040, 3041, 3042, 3715, + 0, 0, 0, 3689, 0, 0, 0, 0, 2108, 0, + 2106, 3933, 0, 1461, 3057, 1462, 1463, 0, 0, 0, + 0, 0, 3873, 3874, 3875, 0, 0, 2865, 2868, 2869, + 2870, 2866, 3184, 2867, 2871, 0, 0, 3525, 3526, 0, + 3936, 0, 3978, 3188, 3939, 3717, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1535, 1536, 1537, + 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, + 1548, 1549, 1550, 1551, 1552, 1553, 1555, 1556, 1557, 1558, + 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, + 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, + 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, + 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, + 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, + 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, + 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, + 1629, 1630, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, + 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1653, 1654, + 1655, 1656, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, + 1678, 1679, 1680, 1681, 1682, 1683, 3934, 3963, 3962, 0, + 1464, 0, 3979, 0, 3953, 0, 0, 0, 0, 0, + 3997, 3959, 0, 3961, 0, 0, 0, 3187, 0, 0, + 3028, 0, 3187, 0, 0, 0, 0, 0, 87, 0, + 0, 0, 3190, 0, 0, 0, 0, 3982, 0, 0, + 0, 0, 0, 3981, 0, 0, 0, 0, 0, 0, + 3208, 0, 0, 0, 0, 3986, 3999, 0, 3866, 0, + 0, 4002, 0, 0, 0, 0, 0, 0, 4133, 0, + 0, 0, 0, 0, 0, 0, 0, 1801, 4004, 0, + 0, 0, 0, 0, 0, 0, 0, 3870, 2615, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, + 0, 4022, 0, 0, 4023, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4047, 0, 0, 0, + 0, 87, 0, 0, 0, 0, 0, 4032, 0, 0, + 0, 1461, 0, 1462, 1463, 0, 0, 0, 4041, 0, + 3100, 0, 3102, 0, 0, 0, 0, 0, 0, 4053, + 0, 0, 0, 0, 4078, 0, 0, 0, 3113, 3114, + 3115, 3116, 0, 4056, 4064, 4061, 4058, 1465, 3340, 4057, + 4055, 4051, 4060, 3890, 4067, 4059, 0, 4086, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3983, + 3357, 3358, 4099, 3359, 3361, 3363, 0, 0, 1523, 0, + 0, 4091, 42, 4109, 4104, 3187, 0, 0, 0, 0, + 0, 4078, 4119, 4117, 0, 0, 0, 1789, 0, 4130, + 0, 3376, 0, 0, 0, 0, 3380, 3381, 3382, 3384, + 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, 3394, + 3395, 3396, 3398, 3400, 3402, 3404, 3406, 3408, 3410, 3412, + 3414, 3416, 3418, 3420, 3422, 3424, 3426, 3428, 3429, 3431, + 3432, 3433, 3435, 1989, 4134, 3437, 4150, 3439, 3440, 3441, + 4153, 4160, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, + 3453, 3454, 3455, 2108, 4166, 2106, 4163, 4159, 4078, 4174, + 4164, 3461, 4162, 4149, 4129, 3466, 4048, 4043, 3184, 3470, + 3471, 1802, 3472, 3474, 4182, 3477, 3479, 4188, 3481, 3482, + 3483, 3484, 4190, 0, 0, 0, 0, 0, 3492, 0, + 0, 0, 0, 0, 0, 0, 0, 3988, 0, 4199, + 4200, 3930, 4198, 0, 0, 0, 0, 0, 0, 0, + 0, 2108, 0, 2106, 4197, 0, 0, 0, 0, 0, + 0, 0, 0, 3516, 3517, 0, 0, 3521, 0, 0, + 0, 4007, 3995, 0, 1815, 1818, 1819, 1820, 1821, 1822, + 1823, 0, 1824, 1825, 1827, 1828, 1826, 1829, 1830, 1803, + 1804, 1805, 1806, 1787, 1788, 1816, 0, 1790, 0, 1791, + 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 0, 0, + 1800, 1807, 1808, 1809, 1810, 0, 1811, 1812, 1813, 1814, + 0, 4125, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4042, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3596, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1750, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3615, 0, + 0, 3619, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1838, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3631, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 947, + 0, 4147, 0, 1697, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3654, 0, + 0, 0, 1012, 0, 2300, 0, 1817, 1013, 0, 0, + 0, 3662, 0, 0, 0, 0, 0, 2107, 3669, 0, + 0, 0, 0, 0, 0, 195, 0, 0, 195, 0, + 0, 0, 720, 0, 0, 0, 0, 726, 0, 0, + 0, 0, 1994, 0, 0, 0, 0, 0, 195, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 726, + 195, 726, 0, 970, 971, 972, 973, 974, 975, 976, + 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, + 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, + 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, + 1007, 1008, 1009, 1010, 1011, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3879, 0, 0, + 0, 0, 0, 0, 0, 0, 3886, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3896, 3897, 3898, 0, + 3900, 0, 3901, 3902, 0, 0, 0, 3905, 3906, 3907, + 3908, 3909, 3910, 3911, 3912, 3913, 3914, 3915, 3916, 3917, + 3918, 3919, 3920, 3921, 3922, 3923, 3924, 3925, 3926, 0, + 3928, 3931, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3652, 0, 0, 3940, 3941, 3942, 3943, + 3944, 3946, 3947, 3949, 3951, 3952, 3954, 0, 0, 0, + 3958, 0, 0, 0, 3960, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3987, + 0, 0, 2059, 2060, 2061, 2062, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2075, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2114, 2115, 0, 0, 0, 0, 2138, + 0, 0, 2142, 2143, 0, 0, 0, 2148, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, + 2168, 2169, 0, 2171, 0, 0, 0, 2193, 2194, 2195, + 2196, 2197, 2198, 2200, 0, 2205, 0, 2207, 2208, 2209, + 0, 2211, 2212, 2213, 0, 2215, 2216, 2217, 2218, 2219, + 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, + 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, + 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, + 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, + 2260, 2264, 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, + 2273, 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2282, + 2283, 2284, 2285, 2286, 0, 0, 0, 0, 0, 2292, + 0, 2294, 0, 2301, 2302, 2303, 2304, 2305, 2306, 0, + 3969, 0, 0, 0, 4012, 0, 0, 0, 0, 0, + 0, 0, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, + 0, 2326, 2327, 2328, 2329, 2330, 0, 0, 4027, 0, + 0, 0, 0, 0, 4030, 0, 4031, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 44, 45, 88, 4046, + 0, 1059, 0, 0, 0, 0, 0, 190, 0, 0, + 0, 0, 0, 0, 92, 0, 0, 0, 48, 76, + 77, 0, 74, 78, 0, 4072, 4073, 0, 2371, 2372, + 129, 0, 151, 0, 75, 0, 0, 0, 0, 4080, + 4082, 4084, 0, 0, 0, 0, 172, 0, 0, 0, + 0, 0, 0, 0, 2410, 0, 0, 4090, 0, 0, + 0, 0, 0, 62, 0, 0, 0, 0, 0, 4112, + 0, 0, 0, 0, 0, 95, 0, 162, 0, 0, + 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 195, 0, 195, 0, + 0, 0, 169, 0, 0, 170, 0, 4131, 0, 0, + 0, 0, 0, 0, 0, 2452, 1697, 0, 0, 0, + 0, 0, 83, 0, 0, 138, 139, 161, 160, 189, + 0, 0, 0, 0, 0, 726, 0, 726, 726, 0, + 0, 4154, 4156, 4158, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 726, 195, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4011, 0, 4179, 0, 0, 0, 0, 0, + 4021, 0, 0, 0, 0, 0, 1509, 0, 0, 0, + 0, 0, 4191, 4192, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 51, 54, 57, 56, + 59, 0, 73, 1012, 0, 82, 79, 0, 1013, 0, + 155, 136, 158, 143, 135, 0, 156, 157, 2107, 0, + 0, 0, 1697, 173, 0, 0, 0, 0, 0, 61, + 91, 90, 179, 144, 71, 72, 58, 0, 0, 0, + 0, 0, 80, 81, 0, 0, 0, 147, 145, 140, + 141, 142, 146, 0, 0, 0, 0, 0, 0, 137, + 0, 0, 0, 0, 0, 0, 0, 0, 148, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 63, 64, 0, 65, 66, + 67, 68, 0, 0, 970, 971, 972, 973, 974, 975, + 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, + 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, + 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, + 1006, 1007, 1008, 1009, 1010, 1011, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 724, 0, 724, 0, 0, 0, 0, 164, - 0, 0, 724, 0, 0, 1506, 724, 0, 0, 724, - 724, 724, 724, 0, 724, 0, 724, 724, 0, 724, - 724, 724, 724, 724, 724, 0, 0, 0, 0, 0, - 0, 0, 1506, 724, 724, 1506, 724, 1506, 195, 724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2624, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2630, 2631, + 2632, 2633, 0, 0, 0, 195, 0, 0, 0, 726, + 726, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, + 0, 0, 0, 159, 0, 0, 0, 0, 0, 0, + 0, 1523, 0, 0, 0, 0, 0, 0, 0, 726, + 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 726, 0, 0, 0, 0, 0, + 0, 195, 0, 0, 0, 726, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 726, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 724, 0, 195, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 724, 0, 0, 724, 0, 195, - 195, 0, 0, 0, 0, 159, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, - 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, - 0, 0, 195, 195, 195, 195, 195, 195, 195, 195, - 195, 724, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1747, 0, 2371, 0, 0, 0, 0, 0, - 0, 0, 2375, 0, 2378, 0, 0, 2049, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 152, 0, 0, 153, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, - 0, 0, 0, 0, 0, 177, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 185, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 724, 724, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 724, 0, 0, 0, 0, 0, 0, 0, 0, - 195, 0, 0, 0, 0, 0, 0, 0, 0, 166, - 171, 168, 174, 175, 176, 178, 180, 181, 182, 183, - 0, 0, 0, 0, 0, 184, 186, 187, 188, 0, - 0, 0, 0, 0, 0, 2049, 0, 0, 0, 0, - 2994, 0, 2536, 0, 0, 0, 0, 0, 0, 724, - 0, 0, 2555, 2556, 0, 0, 2560, 0, 0, 1506, - 0, 0, 0, 0, 3020, 3021, 3022, 0, 2565, 3024, - 0, 0, 3026, 0, 0, 2568, 0, 1506, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 726, 0, + 726, 0, 0, 0, 0, 0, 0, 0, 726, 0, + 0, 1509, 726, 0, 0, 726, 726, 726, 726, 94, + 726, 0, 726, 726, 0, 726, 726, 726, 726, 726, + 726, 0, 152, 0, 0, 153, 0, 0, 1509, 726, + 726, 1509, 726, 1509, 195, 726, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3045, 3046, 3047, 0, 0, 0, 0, 0, - 0, 2571, 0, 0, 3052, 0, 0, 3054, 3055, 3056, - 0, 0, 0, 3057, 3058, 0, 0, 3059, 0, 3060, - 0, 0, 0, 0, 0, 0, 3061, 0, 3062, 0, - 0, 0, 3063, 0, 3064, 0, 0, 3065, 0, 3066, - 0, 3067, 0, 3068, 0, 3069, 0, 3070, 0, 3071, - 0, 3072, 0, 3073, 0, 3074, 0, 3075, 0, 3076, - 0, 3077, 0, 3078, 0, 3079, 0, 3080, 0, 3081, - 0, 3082, 0, 0, 0, 3083, 0, 3084, 0, 3085, - 0, 0, 3086, 0, 3087, 0, 3088, 0, 2258, 3090, - 0, 0, 3092, 0, 0, 3094, 3095, 3096, 3097, 0, - 0, 0, 0, 3098, 2258, 2258, 2258, 2258, 2258, 0, - 0, 2305, 0, 0, 0, 0, 0, 0, 0, 3108, - 0, 0, 0, 0, 0, 0, 0, 3121, 0, 0, - 3125, 0, 0, 0, 0, 0, 0, 0, 0, 3128, - 3129, 3130, 3131, 3132, 3133, 0, 0, 0, 3134, 3135, - 0, 3136, 0, 3137, 0, 0, 195, 0, 0, 0, - 0, 724, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1057, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, - 724, 0, 0, 0, 0, 0, 0, 0, 3170, 0, - 0, 0, 0, 0, 195, 0, 0, 0, 724, 0, - 0, 2305, 195, 0, 195, 0, 195, 195, 0, 0, - 0, 0, 0, 3200, 0, 0, 0, 0, 0, 0, - 0, 724, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 195, 0, 165, 0, 0, 0, + 0, 0, 0, 177, 0, 0, 0, 726, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 726, 0, 0, 726, 0, 195, 195, 0, 0, 0, + 0, 0, 0, 0, 0, 1750, 0, 0, 0, 0, + 0, 0, 195, 0, 185, 0, 0, 0, 0, 195, + 0, 0, 0, 0, 0, 0, 70, 0, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 726, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 166, 171, 168, + 174, 175, 176, 178, 180, 181, 182, 183, 0, 0, + 0, 0, 0, 184, 186, 187, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3263, 0, 0, 0, 724, 0, - 0, 0, 0, 0, 0, 724, 724, 724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 724, 0, 0, 0, 0, - 0, 724, 724, 944, 0, 724, 0, 724, 0, 0, - 0, 0, 0, 724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2869, 0, 724, 0, - 0, 0, 0, 724, 0, 0, 0, 724, 724, 0, - 3356, 0, 0, 0, 0, 703, 0, 0, 0, 0, - 0, 723, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3370, 0, 0, 0, - 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, - 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, - 190, 0, 195, 195, 0, 0, 195, 0, 195, 0, - 2918, 0, 0, 723, 0, 723, 0, 0, 195, 0, - 0, 0, 0, 0, 129, 195, 151, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, - 0, 0, 0, 0, 0, 0, 901, 0, 0, 0, - 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, - 724, 0, 0, 0, 0, 0, 0, 0, 162, 0, - 0, 0, 0, 0, 150, 0, 2967, 2968, 2969, 2970, - 2971, 2972, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 169, 0, 0, 170, 0, 0, 0, - 0, 0, 0, 2049, 2982, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 722, 0, 138, 139, 161, 160, - 189, 0, 0, 0, 0, 0, 2990, 0, 0, 0, - 0, 1506, 0, 2305, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1082, 0, 1089, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3568, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3592, 0, - 0, 155, 136, 158, 143, 135, 0, 156, 157, 0, - 0, 0, 0, 0, 173, 0, 0, 0, 0, 0, - 0, 0, 0, 179, 144, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 147, 145, - 140, 141, 142, 146, 0, 0, 0, 0, 0, 0, - 137, 0, 0, 0, 0, 0, 3612, 0, 3613, 148, - 3614, 0, 3615, 0, 0, 0, 0, 0, 0, 0, - 3618, 3619, 0, 0, 0, 0, 0, 0, 0, 3623, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3624, 0, 3625, 0, 3626, 0, 3627, - 0, 3628, 0, 3629, 0, 3630, 0, 3631, 0, 3632, - 0, 3633, 0, 3634, 0, 3635, 0, 3636, 0, 3637, - 0, 3638, 0, 3639, 0, 0, 3640, 0, 0, 0, - 3641, 0, 3642, 0, 195, 0, 0, 0, 3644, 0, - 0, 0, 195, 0, 0, 0, 0, 0, 164, 0, - 0, 0, 0, 724, 0, 0, 0, 0, 0, 0, - 3661, 0, 0, 0, 0, 0, 0, 724, 0, 3666, - 0, 3667, 3668, 0, 3669, 0, 3670, 0, 0, 0, - 0, 3671, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 195, 0, 0, 0, 0, 195, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3700, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3709, 0, 0, 3711, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3715, 0, 0, 0, - 0, 0, 0, 0, 159, 0, 3253, 0, 0, 0, - 0, 0, 3849, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 724, 0, 0, 0, 0, 0, - 195, 0, 3291, 0, 0, 0, 0, 195, 0, 0, - 0, 0, 0, 0, 0, 0, 3305, 0, 0, 0, - 0, 724, 0, 0, 0, 0, 0, 0, 724, 0, - 0, 0, 724, 724, 0, 0, 3323, 724, 0, 3326, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1506, 724, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 195, 195, 195, 195, - 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 152, 0, 0, 153, 0, 0, 0, - 0, 0, 0, 195, 195, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 723, 1422, 723, - 723, 0, 0, 0, 0, 0, 195, 165, 0, 0, - 3959, 0, 0, 0, 177, 0, 0, 0, 0, 723, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 724, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1505, 0, - 0, 0, 0, 0, 0, 185, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 724, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3485, 0, 0, 0, 0, 0, 166, 171, - 168, 174, 175, 176, 178, 180, 181, 182, 183, 0, - 0, 0, 0, 0, 184, 186, 187, 188, 0, 0, - 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1852, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 129, 0, 151, 0, 0, 0, - 1270, 0, 1270, 1270, 0, 0, 0, 172, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1434, 0, 0, 0, 0, 3546, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, - 0, 0, 724, 0, 150, 0, 0, 3561, 0, 0, - 3562, 3563, 3564, 0, 724, 0, 0, 0, 0, 0, - 0, 0, 0, 169, 0, 4001, 170, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 724, 1856, 1857, 161, 160, - 189, 0, 0, 0, 0, 0, 0, 0, 0, 1505, - 195, 0, 0, 724, 0, 0, 0, 0, 0, 0, - 0, 4015, 0, 0, 4016, 0, 4017, 724, 0, 0, - 0, 1506, 0, 0, 724, 724, 1506, 195, 195, 195, - 195, 195, 0, 0, 0, 0, 0, 0, 0, 195, - 0, 0, 0, 0, 0, 195, 0, 195, 0, 0, - 195, 195, 195, 0, 0, 0, 0, 0, 0, 0, - 0, 723, 723, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 155, 1858, 158, 0, 1855, 195, 156, 157, 0, - 0, 723, 0, 0, 173, 0, 0, 0, 0, 724, - 0, 0, 1506, 179, 0, 0, 723, 724, 4101, 0, - 0, 0, 195, 0, 0, 0, 0, 723, 0, 0, - 0, 0, 0, 0, 0, 0, 195, 723, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4117, 0, 4118, - 0, 4119, 0, 0, 0, 0, 195, 0, 0, 195, - 723, 0, 723, 0, 0, 0, 0, 0, 0, 0, - 723, 0, 0, 1505, 723, 0, 0, 723, 723, 723, - 723, 0, 723, 0, 723, 723, 0, 723, 723, 723, - 723, 723, 723, 0, 0, 0, 0, 0, 0, 0, - 1505, 723, 723, 1505, 723, 1505, 0, 723, 0, 0, - 0, 0, 0, 0, 1703, 1704, 0, 0, 0, 0, - 0, 4168, 0, 4169, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 164, 723, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 723, 0, 1753, 723, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1771, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1829, 0, 0, 0, 0, 724, 0, 0, 0, 0, - 1838, 0, 0, 0, 0, 0, 0, 0, 0, 723, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1082, 0, 1864, 0, 0, 0, 0, - 0, 0, 195, 1873, 0, 0, 0, 1875, 0, 0, - 1878, 1879, 1881, 1881, 159, 1881, 0, 1881, 1881, 0, - 1890, 1881, 1881, 1881, 1881, 1881, 0, 0, 0, 0, - 0, 0, 0, 0, 1910, 1911, 0, 1082, 0, 0, - 1916, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1958, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1979, 0, 195, 1983, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, - 195, 195, 195, 0, 0, 0, 0, 0, 0, 0, - 724, 724, 0, 152, 0, 0, 153, 0, 0, 0, - 0, 0, 1270, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 723, 723, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 165, 0, 723, - 0, 0, 0, 0, 177, 0, 0, 0, 0, 724, - 724, 724, 724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 185, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 723, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1505, 0, 0, - 0, 0, 0, 0, 902, 0, 2110, 0, 0, 0, - 0, 0, 0, 0, 0, 1505, 0, 0, 166, 171, - 168, 174, 175, 176, 178, 180, 181, 182, 183, 3999, - 0, 0, 0, 0, 184, 186, 187, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 193, 0, 0, 668, 0, 0, 0, 0, 0, 1270, - 1270, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2037, 668, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1038, - 0, 0, 0, 0, 0, 724, 0, 724, 0, 195, - 0, 0, 0, 0, 0, 0, 1058, 1058, 0, 0, - 0, 0, 0, 0, 0, 668, 0, 0, 1506, 0, - 0, 0, 195, 0, 0, 724, 0, 724, 0, 0, - 2096, 0, 0, 0, 0, 0, 0, 0, 0, 723, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 726, 726, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 726, 0, 0, + 0, 0, 0, 3003, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3029, 3030, 3031, 0, 0, 3033, 0, 0, 3035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 724, 0, 0, 0, 723, - 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, - 0, 724, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 724, 0, 0, 0, 723, 0, + 0, 0, 0, 0, 0, 0, 726, 0, 3054, 3055, + 3056, 0, 0, 0, 0, 0, 1509, 0, 0, 0, + 3061, 0, 0, 3063, 3064, 3065, 0, 0, 0, 3066, + 3067, 0, 0, 3068, 1509, 3069, 0, 0, 0, 0, + 0, 0, 3070, 0, 3071, 0, 0, 0, 3072, 0, + 3073, 0, 0, 3074, 0, 3075, 0, 3076, 0, 3077, + 0, 3078, 0, 3079, 0, 3080, 0, 3081, 0, 3082, + 0, 3083, 0, 3084, 0, 3085, 0, 3086, 0, 3087, + 0, 3088, 0, 3089, 0, 3090, 0, 3091, 0, 0, + 0, 3092, 0, 3093, 0, 3094, 0, 0, 3095, 0, + 3096, 0, 3097, 0, 2264, 3099, 0, 0, 3101, 0, + 0, 3103, 3104, 3105, 3106, 0, 0, 0, 0, 3107, + 2264, 2264, 2264, 2264, 2264, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3117, 0, 0, 0, 0, + 0, 0, 0, 3130, 0, 0, 3134, 0, 0, 0, + 0, 0, 0, 0, 0, 3137, 3138, 3139, 3140, 3141, + 3142, 0, 0, 0, 3143, 3144, 0, 3145, 2311, 3146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 723, 0, 0, 723, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 723, + 0, 0, 0, 1059, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 195, 3179, 0, 0, 0, 726, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 724, 0, - 0, 0, 1270, 0, 0, 724, 0, 724, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 190, 0, 3209, + 0, 0, 0, 0, 195, 0, 0, 726, 2940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 723, 0, 0, 0, - 0, 0, 0, 723, 723, 723, 724, 0, 0, 0, + 129, 195, 151, 0, 0, 726, 0, 0, 2311, 195, + 0, 195, 0, 195, 195, 0, 172, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 726, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2342, 723, 0, 0, 0, 0, 0, 723, - 723, 0, 0, 723, 0, 723, 0, 0, 0, 0, - 0, 723, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2355, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1753, - 0, 0, 1270, 0, 0, 0, 723, 0, 0, 0, - 0, 723, 0, 0, 0, 723, 723, 0, 0, 0, - 0, 0, 1082, 0, 0, 0, 0, 0, 0, 0, + 3272, 0, 0, 0, 0, 0, 0, 162, 0, 0, + 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 169, 0, 0, 170, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 726, 0, 0, 0, 0, + 0, 0, 726, 726, 726, 1859, 1860, 161, 160, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 726, 0, 0, 0, 0, 0, 726, 726, + 0, 0, 726, 0, 726, 0, 0, 0, 0, 0, + 726, 946, 0, 0, 0, 0, 3365, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 724, 0, 0, 0, 0, 1089, - 0, 0, 0, 0, 0, 0, 2468, 2469, 2470, 0, - 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1082, 0, 724, 195, - 0, 0, 1089, 1873, 0, 0, 1873, 0, 1873, 0, - 0, 0, 0, 0, 2500, 0, 0, 0, 723, 0, + 0, 0, 3379, 0, 0, 726, 0, 0, 0, 0, + 726, 0, 0, 0, 726, 726, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 705, 0, 0, 0, 0, 0, 725, + 155, 1861, 158, 0, 1858, 0, 156, 157, 0, 0, + 0, 0, 195, 173, 0, 0, 0, 0, 0, 195, + 0, 0, 179, 0, 0, 0, 0, 0, 0, 195, + 195, 0, 0, 195, 0, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 0, 0, 0, 0, + 0, 725, 195, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1082, - 0, 0, 0, 0, 2096, 0, 0, 0, 2096, 2096, - 0, 0, 0, 0, 724, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 724, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1506, 724, 0, 724, 0, 1505, - 0, 723, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, + 0, 0, 0, 0, 0, 0, 0, 726, 0, 0, + 903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 724, 2305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 195, 724, 0, 0, 0, 0, 668, - 0, 668, 0, 0, 0, 95, 0, 0, 1010, 0, - 0, 2574, 950, 1011, 963, 964, 965, 951, 0, 0, - 952, 953, 0, 954, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 724, 0, 0, 959, 0, 966, - 967, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 724, 0, - 0, 668, 0, 195, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 724, 0, 724, - 0, 0, 0, 0, 1270, 0, 0, 3299, 3300, 1507, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 968, - 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, - 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, - 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, - 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, - 1009, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 723, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3301, 0, 0, 723, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2882, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1509, 0, 2311, 0, 0, 0, 0, 0, 0, + 0, 3577, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3601, 0, 0, 0, 0, 0, + 1084, 0, 1091, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 159, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3621, 0, 3622, 0, 3623, 0, 3624, 0, + 0, 0, 0, 0, 0, 0, 3627, 3628, 0, 0, + 0, 0, 0, 0, 0, 3632, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3633, + 0, 3634, 0, 3635, 0, 3636, 0, 3637, 0, 3638, + 0, 3639, 0, 3640, 0, 3641, 0, 3642, 0, 3643, + 0, 3644, 0, 3645, 0, 3646, 0, 3647, 0, 3648, + 0, 0, 3649, 0, 0, 0, 3650, 0, 3651, 0, + 0, 0, 0, 0, 3653, 0, 0, 0, 0, 0, + 0, 0, 152, 0, 0, 153, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3670, 0, 0, 0, + 0, 0, 0, 0, 0, 3675, 0, 3676, 3677, 0, + 3678, 0, 3679, 0, 195, 0, 165, 3680, 0, 0, + 0, 0, 195, 177, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 726, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3709, 0, 0, 726, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3718, 0, 0, + 3720, 0, 0, 0, 185, 0, 0, 0, 0, 0, + 0, 195, 3724, 0, 0, 0, 195, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3858, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 166, 171, 168, + 174, 175, 176, 178, 180, 181, 182, 183, 0, 0, + 0, 0, 0, 184, 186, 187, 188, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 726, 0, 0, 0, 0, 0, + 195, 0, 0, 0, 0, 0, 0, 195, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 726, 0, 0, 0, 0, 0, 0, 726, 0, + 0, 0, 726, 726, 0, 0, 0, 726, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1509, 726, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 195, 195, 195, 195, + 195, 195, 0, 0, 0, 0, 3968, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3302, 3303, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 195, 725, 1424, 725, + 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 725, + 1703, 0, 726, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 723, 0, 0, 0, 0, 0, 0, 0, - 1507, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 723, - 0, 0, 0, 0, 0, 0, 723, 0, 0, 0, - 723, 723, 0, 0, 2817, 723, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2832, 0, - 0, 1505, 723, 0, 915, 0, 0, 0, 668, 0, - 919, 0, 0, 0, 916, 917, 0, 0, 0, 918, - 920, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1038, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 668, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 723, 0, 0, - 0, 0, 0, 0, 0, 2914, 0, 0, 0, 0, + 726, 0, 0, 0, 0, 0, 0, 0, 0, 669, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2355, 0, 1507, 0, 0, 0, 0, 2939, - 0, 0, 0, 1873, 1873, 723, 0, 0, 2944, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1507, 0, 0, 1507, 2955, 1507, 668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1932, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 668, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1985, 668, + 0, 1088, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1272, 0, 1272, 1272, + 0, 4010, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1436, 0, + 0, 0, 0, 0, 0, 726, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 726, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4024, 0, 0, + 4025, 0, 4026, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 726, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 668, 0, 0, 0, 0, - 0, 0, 668, 0, 0, 0, 0, 0, 0, 0, - 2096, 2011, 2012, 668, 668, 668, 668, 668, 668, 668, - 723, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 723, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 195, 0, 0, 726, 0, 0, 1508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2096, 0, - 0, 0, 0, 723, 0, 0, 0, 0, 0, 0, + 726, 0, 0, 0, 1509, 0, 0, 726, 726, 1509, + 195, 195, 195, 195, 195, 0, 0, 0, 0, 0, + 0, 0, 195, 0, 0, 0, 0, 0, 195, 0, + 195, 0, 0, 195, 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 723, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 723, 0, 0, 0, 1505, - 0, 0, 723, 723, 1505, 0, 0, 0, 0, 0, + 0, 725, 725, 0, 4110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, + 0, 0, 0, 4126, 0, 4127, 0, 4128, 0, 0, + 0, 725, 726, 0, 0, 1509, 0, 0, 0, 0, + 726, 0, 0, 0, 0, 195, 725, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 725, 0, 195, + 0, 0, 0, 0, 0, 0, 0, 725, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, + 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, + 725, 0, 725, 0, 0, 0, 0, 4177, 0, 4178, + 725, 0, 0, 1508, 725, 0, 0, 725, 725, 725, + 725, 0, 725, 0, 725, 725, 0, 725, 725, 725, + 725, 725, 725, 0, 0, 0, 0, 0, 0, 0, + 1508, 725, 725, 1508, 725, 1508, 0, 725, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1706, 1707, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 725, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 725, 0, 0, 725, 0, 0, 0, 0, + 1756, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1774, 0, 0, 726, 0, + 0, 0, 0, 0, 0, 0, 1832, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1841, 0, 0, 725, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 195, 0, 0, 0, 1084, + 0, 1867, 0, 0, 0, 0, 0, 0, 0, 1876, + 0, 0, 0, 1878, 0, 0, 1881, 1882, 1884, 1884, + 0, 1884, 0, 1884, 1884, 0, 1893, 1884, 1884, 1884, + 1884, 1884, 0, 0, 0, 0, 0, 0, 0, 0, + 1913, 1914, 0, 1084, 0, 0, 1919, 0, 0, 0, + 0, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1961, 0, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1982, 0, 0, 1986, 0, 0, 0, 0, 904, + 195, 0, 0, 195, 195, 195, 0, 0, 0, 0, + 0, 0, 0, 726, 726, 0, 0, 1208, 0, 1214, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1272, 0, + 0, 0, 0, 0, 0, 0, 725, 725, 0, 0, + 0, 0, 0, 0, 0, 193, 0, 0, 670, 725, + 0, 0, 726, 726, 726, 726, 190, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1855, 670, 1437, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, + 0, 151, 0, 0, 1040, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, + 0, 1060, 1060, 0, 0, 0, 0, 0, 725, 0, + 670, 0, 0, 0, 0, 0, 0, 0, 1508, 0, + 0, 0, 0, 0, 0, 0, 162, 2116, 0, 0, + 0, 0, 150, 0, 0, 0, 1508, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 169, 0, 0, 170, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1859, 1860, 161, 160, 189, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1272, 1272, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2040, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 726, 0, + 726, 0, 195, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1509, 0, 0, 0, 195, 0, 0, 726, 0, + 726, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2102, 0, 0, + 725, 0, 0, 0, 0, 0, 0, 0, 0, 155, + 1861, 158, 0, 1858, 0, 156, 157, 0, 0, 0, + 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, + 0, 179, 0, 0, 0, 0, 0, 0, 726, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 725, 195, 0, 0, 726, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 726, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 725, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 725, 0, 0, + 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1762, 0, 0, 0, 0, 0, 0, + 0, 726, 0, 0, 0, 0, 0, 0, 726, 0, + 726, 0, 1779, 0, 0, 0, 164, 0, 0, 1272, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 725, 0, 726, + 0, 0, 0, 0, 725, 725, 725, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 725, 0, 0, 0, 0, 2348, + 725, 725, 0, 0, 725, 0, 725, 0, 0, 0, + 0, 0, 725, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1918, 0, 0, 2361, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 159, 0, 0, 0, 1756, 725, 0, 1272, + 0, 0, 725, 0, 0, 0, 725, 725, 0, 0, + 1963, 0, 0, 0, 0, 0, 0, 0, 0, 1084, + 0, 0, 0, 0, 0, 0, 0, 1990, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2001, 0, 0, 0, 0, 0, 0, + 2005, 0, 0, 0, 0, 0, 0, 726, 0, 0, + 0, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 0, 0, + 0, 0, 0, 195, 0, 0, 1091, 0, 0, 0, + 0, 0, 0, 2474, 2475, 2476, 0, 0, 0, 0, + 0, 726, 195, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 0, 1084, 153, 0, 0, 0, 0, 1091, + 1876, 0, 0, 1876, 0, 1876, 0, 0, 0, 725, + 0, 2506, 0, 0, 0, 0, 670, 0, 670, 0, + 0, 0, 0, 0, 0, 165, 0, 0, 0, 0, + 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1084, 726, 0, 0, + 0, 2102, 0, 0, 0, 2102, 2102, 726, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1509, 726, 0, + 726, 0, 0, 185, 0, 0, 0, 0, 670, 0, + 0, 0, 0, 1508, 0, 725, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 726, 2311, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1510, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 166, 171, 168, 174, + 175, 176, 178, 180, 181, 182, 183, 0, 0, 0, + 0, 0, 184, 186, 187, 188, 195, 726, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2052, 0, 0, + 0, 0, 0, 0, 0, 95, 0, 0, 1012, 0, + 0, 0, 952, 1013, 965, 966, 967, 953, 2580, 0, + 954, 955, 0, 956, 0, 0, 0, 726, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 961, 0, 968, + 969, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 726, 0, 0, 0, 0, 195, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 726, 0, 726, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3308, 3309, 0, + 0, 0, 0, 0, 1272, 0, 0, 0, 0, 970, + 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, + 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, + 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, + 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, + 1011, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 725, 0, 0, 0, 0, + 0, 0, 3310, 0, 0, 0, 0, 0, 0, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3248, 0, 0, 0, 0, - 0, 0, 0, 3110, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1270, 0, 723, 0, 0, - 1505, 0, 0, 0, 0, 723, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 668, - 0, 0, 0, 0, 0, 0, 1881, 0, 0, 0, + 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3155, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3330, 1270, 0, - 0, 0, 0, 0, 0, 3182, 1881, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1507, 0, + 0, 0, 0, 0, 2891, 0, 0, 0, 1040, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3311, 3312, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 670, 0, 0, 0, 0, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2377, 0, 0, 0, 0, 0, 0, 0, + 2381, 0, 2384, 725, 0, 2052, 0, 0, 0, 0, + 725, 0, 0, 0, 725, 725, 0, 0, 0, 725, + 0, 1510, 0, 0, 2826, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 917, 1508, 725, 0, 2841, 0, + 921, 0, 0, 0, 918, 919, 0, 0, 1510, 920, + 922, 1510, 0, 1510, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1935, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1082, 0, 0, 0, 0, 0, 0, 0, 2355, 0, + 0, 0, 0, 0, 0, 1988, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 723, 0, 0, 0, 0, 0, 0, + 0, 0, 670, 0, 725, 0, 0, 0, 0, 670, + 0, 0, 0, 0, 0, 2923, 0, 0, 2014, 2015, + 670, 670, 670, 670, 670, 670, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2361, 0, 0, 0, 0, 0, 0, 2948, + 0, 0, 725, 1876, 1876, 0, 0, 0, 2953, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2964, 0, 0, 0, 0, + 0, 0, 0, 2052, 0, 0, 0, 0, 0, 0, + 2542, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2561, 2562, 0, 0, 2566, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2571, 0, 0, 0, + 0, 0, 0, 2574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2102, 0, 0, 0, 725, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1985, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 725, 2102, 0, 0, 0, 0, 670, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1932, 0, 0, 0, 0, - 0, 0, 0, 0, 3536, 0, 0, 0, 0, 0, - 0, 1058, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1038, 0, 0, 0, + 0, 0, 725, 0, 0, 0, 1508, 0, 0, 725, + 725, 1508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 668, 0, 0, 1829, 0, 723, 723, - 1985, 668, 0, 668, 0, 668, 2394, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3257, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3119, 0, 0, 0, + 0, 0, 0, 0, 725, 0, 0, 1508, 1272, 0, + 0, 0, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 723, 723, 723, - 723, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1884, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3164, 0, 0, + 0, 0, 0, 0, 3339, 0, 0, 0, 0, 0, + 0, 1272, 0, 0, 0, 0, 0, 0, 3191, 1884, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1935, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060, + 0, 0, 0, 1084, 0, 0, 0, 0, 0, 0, + 0, 2361, 0, 0, 1040, 0, 0, 0, 0, 0, + 725, 0, 0, 0, 0, 0, 0, 2878, 0, 0, + 0, 670, 0, 0, 0, 0, 0, 0, 1988, 670, + 0, 670, 0, 670, 2400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2355, 2355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2927, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3600, 3601, 3602, 3603, 668, 0, 0, 0, 0, 0, - 0, 668, 0, 723, 0, 723, 0, 0, 0, 0, - 0, 668, 668, 0, 0, 668, 0, 2562, 0, 0, - 0, 0, 0, 0, 0, 0, 1505, 668, 0, 0, - 0, 0, 0, 723, 668, 723, 0, 0, 0, 0, + 0, 3545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 668, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2976, 2977, 2978, + 2979, 2980, 2981, 0, 0, 725, 725, 0, 0, 1832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2052, 2991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 723, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 723, + 0, 0, 0, 0, 0, 0, 0, 2999, 0, 0, + 0, 0, 0, 0, 725, 725, 725, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 723, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 670, 0, 0, 0, 0, 0, 0, 670, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 670, + 670, 0, 0, 670, 0, 2568, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, + 0, 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1507, 0, 1985, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3677, 0, 3677, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3705, 0, 3707, 0, - 0, 0, 0, 0, 0, 0, 723, 0, 0, 0, - 0, 0, 0, 723, 0, 723, 0, 0, 0, 0, + 0, 0, 0, 0, 2361, 2361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 723, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3872, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3609, 3610, 3611, 3612, 0, 0, 0, + 725, 1510, 725, 1988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1508, 0, 0, 0, 0, 0, 0, + 725, 0, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3677, - 0, 0, 0, 0, 0, 0, 3677, 0, 3677, 0, - 0, 0, 0, 668, 0, 0, 0, 0, 0, 0, - 0, 1932, 723, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 723, 0, 0, 0, + 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 725, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 668, 0, 0, 0, 0, 668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3686, + 0, 3686, 0, 0, 0, 0, 0, 0, 0, 0, + 3262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3714, + 0, 3716, 0, 725, 0, 0, 3300, 0, 0, 0, + 725, 0, 725, 0, 0, 0, 0, 0, 0, 0, + 3314, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, + 3332, 725, 1935, 3335, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3881, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1272, 0, + 0, 670, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 723, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 723, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1505, 723, 0, 723, 0, 0, 0, 668, - 0, 0, 0, 0, 0, 0, 2924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 723, 723, 0, 0, 0, 2355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1507, 0, 0, 0, 0, 0, 0, 2355, - 0, 0, 723, 0, 0, 668, 668, 668, 668, 668, - 668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 668, 668, 0, 0, 0, 0, 0, 0, - 0, 0, 723, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 668, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4019, 723, 0, 0, 0, - 0, 0, 0, 0, 0, 4027, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 723, 2355, 723, 4035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3686, 0, 0, 0, 0, 0, 0, 3686, + 670, 3686, 0, 0, 0, 0, 0, 2933, 0, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1270, 1270, 0, 3737, 3739, 3738, 3802, - 3803, 3804, 3805, 3806, 3807, 3808, 794, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2361, 0, 0, 0, 0, 0, 3494, 0, 0, 0, + 0, 0, 0, 725, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1510, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 670, 670, 670, 670, + 670, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4085, 0, 0, 0, 0, + 0, 0, 0, 670, 670, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 725, + 0, 0, 0, 0, 0, 0, 670, 0, 0, 725, + 0, 3555, 0, 0, 0, 0, 0, 0, 0, 1508, + 725, 0, 725, 0, 0, 0, 0, 0, 0, 0, + 0, 3570, 0, 0, 3571, 3572, 3573, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 725, 725, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 725, + 0, 0, 2361, 0, 0, 0, 0, 3746, 3748, 3747, + 3811, 3812, 3813, 3814, 3815, 3816, 3817, 796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4027, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1829, 0, - 4085, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 725, 0, 0, 0, 0, 4028, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4036, 0, + 0, 0, 725, 0, 725, 0, 0, 0, 0, 2361, + 0, 4044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1272, 1272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1058, 0, 668, + 0, 0, 0, 0, 0, 0, 0, 0, 4094, 0, + 0, 1060, 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1510, 0, 0, 0, 0, 1510, + 670, 670, 670, 670, 670, 0, 0, 0, 4036, 0, + 0, 0, 3207, 0, 0, 0, 0, 0, 1935, 0, + 670, 0, 0, 670, 3215, 1988, 0, 0, 0, 0, + 0, 0, 2361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1507, 0, 0, 0, 0, 1507, 668, 668, 668, 668, - 668, 0, 0, 0, 0, 0, 0, 0, 3198, 0, - 0, 0, 0, 0, 1932, 0, 668, 0, 0, 668, - 3206, 1985, 0, 0, 3743, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3751, - 3752, 0, 0, 3827, 3826, 3825, 0, 0, 3823, 3824, - 3822, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 668, 0, 0, 0, 0, + 0, 1832, 0, 4094, 0, 3752, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 670, + 3760, 3761, 0, 0, 3836, 3835, 3834, 0, 0, 3832, + 3833, 3831, 0, 0, 0, 1510, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1507, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 668, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3828, 915, 668, 770, 771, 3829, 3830, - 919, 3831, 773, 774, 916, 917, 0, 768, 772, 918, - 920, 0, 0, 0, 0, 668, 0, 0, 668, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 670, + 0, 0, 670, 0, 3837, 917, 0, 772, 773, 3838, + 3839, 921, 3840, 775, 776, 918, 919, 0, 770, 774, + 920, 922, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3734, 3735, 3736, 3740, - 3741, 3742, 3753, 3800, 3801, 3809, 3811, 871, 3810, 3812, - 3813, 3814, 3817, 3818, 3819, 3820, 3815, 3816, 3821, 3717, - 3721, 3718, 3719, 3720, 3732, 3722, 3723, 3724, 3725, 3726, - 3727, 3728, 3729, 3730, 3731, 3733, 3832, 3833, 3834, 3835, - 3836, 3837, 3746, 3750, 3749, 3747, 3748, 3744, 3745, 3772, - 3771, 3773, 3774, 3775, 3776, 3777, 3778, 3780, 3779, 3781, - 3782, 3783, 3784, 3785, 3786, 3754, 3755, 3758, 3759, 3757, - 3756, 3760, 3769, 3770, 3761, 3762, 3763, 3764, 3765, 3766, - 3768, 3767, 3787, 3788, 3789, 3790, 3791, 3793, 3792, 3796, - 3797, 3795, 3794, 3799, 3798, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 921, 0, - 922, 0, 0, 926, 0, 0, 0, 928, 927, 0, - 929, 891, 890, 0, 0, 923, 924, 0, 925, 0, - 0, 668, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3743, 3744, 3745, + 3749, 3750, 3751, 3762, 3809, 3810, 3818, 3820, 873, 3819, + 3821, 3822, 3823, 3826, 3827, 3828, 3829, 3824, 3825, 3830, + 3726, 3730, 3727, 3728, 3729, 3741, 3731, 3732, 3733, 3734, + 3735, 3736, 3737, 3738, 3739, 3740, 3742, 3841, 3842, 3843, + 3844, 3845, 3846, 3755, 3759, 3758, 3756, 3757, 3753, 3754, + 3781, 3780, 3782, 3783, 3784, 3785, 3786, 3787, 3789, 3788, + 3790, 3791, 3792, 3793, 3794, 3795, 3763, 3764, 3767, 3768, + 3766, 3765, 3769, 3778, 3779, 3770, 3771, 3772, 3773, 3774, + 3775, 3777, 3776, 3796, 3797, 3798, 3799, 3800, 3802, 3801, + 3805, 3806, 3804, 3803, 3808, 3807, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 670, 0, 0, 0, 923, + 0, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 668, 0, 0, - 0, 0, 0, 3838, 3839, 3840, 3841, 3842, 3843, 3844, - 3845, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 668, 0, 0, 668, - 668, 668, 0, 0, 0, 0, 0, 0, 0, 0, + 670, 0, 0, 4008, 3847, 3848, 3849, 3850, 3851, 3852, + 3853, 3854, 0, 0, 0, 0, 0, 0, 0, 0, + 670, 0, 0, 670, 670, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2790,19 +2794,18 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1932, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1507, 0, 0, - 0, 1932, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1935, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1510, 0, 0, 0, 1935, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1932, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1935, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2828,4475 +2831,4495 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1932, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1935, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 393, 0, 0, 0, 0, 1405, 1391, 523, 0, 1333, - 1408, 1302, 1321, 1418, 1324, 1327, 1370, 1280, 1348, 413, - 1318, 1273, 1306, 1275, 1313, 1276, 1304, 1335, 269, 1301, - 1393, 1352, 1407, 363, 266, 1282, 1307, 427, 1323, 203, - 1372, 484, 251, 374, 371, 578, 281, 272, 268, 249, - 316, 382, 425, 513, 419, 1414, 367, 1358, 0, 494, - 398, 0, 0, 1507, 1337, 1397, 1346, 1384, 1332, 1371, - 1290, 1357, 1409, 1319, 1367, 1410, 322, 247, 324, 202, - 410, 495, 285, 0, 0, 0, 0, 4059, 946, 0, - 0, 0, 4057, 4060, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 348, 357, 356, 337, 338, - 340, 342, 347, 354, 360, 1315, 1364, 602, 1404, 1316, - 1366, 264, 320, 271, 263, 575, 1415, 1396, 1279, 1345, - 1403, 1340, 1932, 0, 228, 1406, 1339, 0, 1369, 0, - 1421, 1274, 1360, 0, 1277, 1281, 1417, 1401, 1310, 274, - 0, 0, 0, 0, 0, 0, 0, 1336, 1347, 1381, - 1385, 1330, 0, 0, 0, 0, 0, 0, 0, 0, - 1308, 0, 1356, 0, 0, 0, 1286, 1278, 0, 0, + 0, 0, 670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 394, 0, 0, 0, 0, 0, 1407, 1393, 525, + 0, 1335, 1410, 1304, 1323, 1420, 1326, 1329, 1372, 1282, + 1350, 414, 1320, 1308, 1277, 1315, 1278, 1306, 1337, 270, + 1303, 1395, 1354, 1409, 364, 267, 1284, 1275, 204, 503, + 1309, 428, 1325, 203, 1374, 485, 252, 375, 372, 580, + 282, 273, 269, 250, 317, 383, 426, 515, 420, 1416, + 368, 1360, 0, 495, 399, 0, 0, 1510, 1339, 1399, + 1348, 1386, 1334, 1373, 1292, 1359, 1411, 1321, 1369, 1412, + 323, 248, 325, 202, 411, 496, 286, 0, 0, 0, + 0, 4068, 948, 0, 0, 0, 4066, 4069, 0, 0, + 0, 0, 238, 0, 0, 245, 0, 0, 0, 349, + 358, 357, 338, 339, 341, 343, 348, 355, 361, 1317, + 1366, 604, 1406, 1318, 1368, 265, 321, 272, 264, 577, + 1417, 1398, 1281, 1347, 1405, 1342, 1935, 0, 229, 1408, + 1341, 0, 1371, 0, 1423, 1276, 1362, 0, 1279, 1283, + 1419, 1403, 1312, 275, 0, 0, 0, 0, 0, 0, + 0, 1338, 1349, 1383, 1387, 1332, 0, 0, 0, 0, + 0, 0, 0, 0, 1310, 0, 1358, 0, 0, 0, + 1288, 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1985, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1334, 0, 0, 0, 0, 1289, 0, 1309, 1382, 0, - 1272, 296, 1283, 399, 256, 0, 450, 1389, 1400, 1331, - 620, 1402, 1329, 1328, 1376, 1287, 1395, 1322, 362, 1285, - 329, 197, 224, 0, 1320, 409, 458, 470, 1394, 1305, - 1314, 252, 1312, 468, 423, 597, 232, 283, 455, 429, - 466, 437, 286, 1355, 1374, 467, 369, 580, 447, 594, - 621, 622, 262, 403, 607, 517, 615, 639, 225, 259, - 417, 502, 600, 491, 394, 576, 577, 328, 490, 294, - 201, 366, 627, 223, 476, 368, 241, 230, 582, 604, - 298, 288, 453, 634, 212, 512, 592, 238, 480, 0, - 0, 642, 246, 501, 214, 589, 500, 390, 325, 326, - 213, 0, 454, 267, 292, 0, 0, 257, 412, 584, - 585, 255, 643, 227, 614, 219, 1284, 613, 405, 579, - 590, 391, 380, 218, 588, 389, 379, 333, 352, 353, - 279, 306, 444, 372, 445, 305, 307, 401, 400, 402, - 206, 601, 0, 207, 0, 496, 603, 644, 449, 211, - 233, 234, 236, 1300, 278, 282, 290, 293, 302, 303, - 312, 364, 416, 443, 439, 448, 1390, 574, 595, 608, - 619, 625, 626, 628, 629, 630, 631, 632, 635, 633, - 404, 310, 492, 332, 370, 1379, 1420, 422, 469, 239, - 599, 493, 199, 1294, 1299, 1292, 0, 253, 254, 1361, - 570, 1295, 1293, 1350, 1351, 1296, 1411, 1412, 1413, 1398, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 659, 660, 661, 662, 640, 503, - 509, 504, 505, 506, 507, 508, 0, 510, 1383, 1288, - 0, 1297, 1298, 395, 1392, 586, 587, 663, 381, 483, - 596, 334, 346, 349, 339, 358, 0, 359, 335, 336, - 341, 343, 344, 345, 350, 351, 355, 361, 248, 209, - 387, 396, 573, 311, 215, 216, 217, 519, 520, 521, - 522, 611, 612, 616, 204, 459, 460, 461, 462, 291, - 606, 308, 465, 464, 330, 331, 376, 446, 535, 537, - 548, 552, 554, 556, 562, 565, 536, 538, 549, 553, - 555, 557, 563, 566, 525, 527, 529, 531, 544, 543, - 540, 568, 569, 546, 551, 530, 542, 547, 560, 567, - 564, 524, 528, 532, 541, 559, 558, 539, 550, 561, - 545, 533, 526, 534, 1354, 196, 220, 365, 1416, 451, - 287, 641, 610, 481, 605, 205, 222, 1291, 261, 1303, - 1311, 0, 1317, 1325, 1326, 1338, 1341, 1342, 1343, 1344, - 1362, 1363, 1365, 1373, 1375, 1378, 1380, 1387, 1399, 1419, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 309, 317, 318, 321, 327, 377, 383, 384, - 385, 386, 406, 407, 408, 411, 414, 415, 418, 420, - 421, 424, 428, 432, 433, 434, 436, 438, 440, 452, - 457, 471, 472, 473, 474, 475, 478, 479, 485, 486, - 487, 488, 489, 497, 498, 511, 581, 583, 598, 617, - 623, 477, 300, 301, 441, 442, 313, 314, 637, 638, - 299, 593, 624, 591, 636, 618, 435, 375, 1353, 1359, - 378, 280, 304, 319, 1368, 609, 499, 226, 463, 289, - 250, 1386, 1388, 210, 245, 229, 258, 273, 276, 323, - 388, 397, 426, 431, 295, 270, 243, 456, 240, 482, - 514, 515, 516, 518, 392, 265, 430, 1349, 1377, 373, - 571, 572, 315, 393, 0, 0, 0, 0, 1405, 1391, - 523, 0, 1333, 1408, 1302, 1321, 1418, 1324, 1327, 1370, - 1280, 1348, 413, 1318, 1273, 1306, 1275, 1313, 1276, 1304, - 1335, 269, 1301, 1393, 1352, 1407, 363, 266, 1282, 1307, - 427, 1323, 203, 1372, 484, 251, 374, 371, 578, 281, - 272, 268, 249, 316, 382, 425, 513, 419, 1414, 367, - 1358, 0, 494, 398, 0, 0, 0, 1337, 1397, 1346, - 1384, 1332, 1371, 1290, 1357, 1409, 1319, 1367, 1410, 322, - 247, 324, 202, 410, 495, 285, 0, 0, 0, 0, - 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 348, 357, - 356, 337, 338, 340, 342, 347, 354, 360, 1315, 1364, - 602, 1404, 1316, 1366, 264, 320, 271, 263, 575, 1415, - 1396, 1279, 1345, 1403, 1340, 0, 0, 228, 1406, 1339, - 0, 1369, 0, 1421, 1274, 1360, 0, 1277, 1281, 1417, - 1401, 1310, 274, 0, 0, 0, 0, 0, 0, 0, - 1336, 1347, 1381, 1385, 1330, 0, 0, 0, 0, 0, - 0, 3207, 0, 1308, 0, 1356, 0, 0, 0, 1286, - 1278, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1334, 0, 0, 0, 0, 1289, 0, - 1309, 1382, 0, 1272, 296, 1283, 399, 256, 0, 450, - 1389, 1400, 1331, 620, 1402, 1329, 1328, 1376, 1287, 1395, - 1322, 362, 1285, 329, 197, 224, 0, 1320, 409, 458, - 470, 1394, 1305, 1314, 252, 1312, 468, 423, 597, 232, - 283, 455, 429, 466, 437, 286, 1355, 1374, 467, 369, - 580, 447, 594, 621, 622, 262, 403, 607, 517, 615, - 639, 225, 259, 417, 502, 600, 491, 394, 576, 577, - 328, 490, 294, 201, 366, 627, 223, 476, 368, 241, - 230, 582, 604, 298, 288, 453, 634, 212, 512, 592, - 238, 480, 0, 0, 642, 246, 501, 214, 589, 500, - 390, 325, 326, 213, 0, 454, 267, 292, 0, 0, - 257, 412, 584, 585, 255, 643, 227, 614, 219, 1284, - 613, 405, 579, 590, 391, 380, 218, 588, 389, 379, - 333, 352, 353, 279, 306, 444, 372, 445, 305, 307, - 401, 400, 402, 206, 601, 0, 207, 0, 496, 603, - 644, 449, 211, 233, 234, 236, 1300, 278, 282, 290, - 293, 302, 303, 312, 364, 416, 443, 439, 448, 1390, - 574, 595, 608, 619, 625, 626, 628, 629, 630, 631, - 632, 635, 633, 404, 310, 492, 332, 370, 1379, 1420, - 422, 469, 239, 599, 493, 199, 1294, 1299, 1292, 0, - 253, 254, 1361, 570, 1295, 1293, 1350, 1351, 1296, 1411, - 1412, 1413, 1398, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, - 662, 640, 503, 509, 504, 505, 506, 507, 508, 0, - 510, 1383, 1288, 0, 1297, 1298, 395, 1392, 586, 587, - 663, 381, 483, 596, 334, 346, 349, 339, 358, 0, - 359, 335, 336, 341, 343, 344, 345, 350, 351, 355, - 361, 248, 209, 387, 396, 573, 311, 215, 216, 217, - 519, 520, 521, 522, 611, 612, 616, 204, 459, 460, - 461, 462, 291, 606, 308, 465, 464, 330, 331, 376, - 446, 535, 537, 548, 552, 554, 556, 562, 565, 536, - 538, 549, 553, 555, 557, 563, 566, 525, 527, 529, - 531, 544, 543, 540, 568, 569, 546, 551, 530, 542, - 547, 560, 567, 564, 524, 528, 532, 541, 559, 558, - 539, 550, 561, 545, 533, 526, 534, 1354, 196, 220, - 365, 1416, 451, 287, 641, 610, 481, 605, 205, 222, - 1291, 261, 1303, 1311, 0, 1317, 1325, 1326, 1338, 1341, - 1342, 1343, 1344, 1362, 1363, 1365, 1373, 1375, 1378, 1380, - 1387, 1399, 1419, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 309, 317, 318, 321, 327, - 377, 383, 384, 385, 386, 406, 407, 408, 411, 414, - 415, 418, 420, 421, 424, 428, 432, 433, 434, 436, - 438, 440, 452, 457, 471, 472, 473, 474, 475, 478, - 479, 485, 486, 487, 488, 489, 497, 498, 511, 581, - 583, 598, 617, 623, 477, 300, 301, 441, 442, 313, - 314, 637, 638, 299, 593, 624, 591, 636, 618, 435, - 375, 1353, 1359, 378, 280, 304, 319, 1368, 609, 499, - 226, 463, 289, 250, 1386, 1388, 210, 245, 229, 258, - 273, 276, 323, 388, 397, 426, 431, 295, 270, 243, - 456, 240, 482, 514, 515, 516, 518, 392, 265, 430, - 1349, 1377, 373, 571, 572, 315, 393, 0, 0, 0, - 0, 1405, 1391, 523, 0, 1333, 1408, 1302, 1321, 1418, - 1324, 1327, 1370, 1280, 1348, 413, 1318, 1273, 1306, 1275, - 1313, 1276, 1304, 1335, 269, 1301, 1393, 1352, 1407, 363, - 266, 1282, 1307, 427, 1323, 203, 1372, 484, 251, 374, - 371, 578, 281, 272, 268, 249, 316, 382, 425, 513, - 419, 1414, 367, 1358, 0, 494, 398, 0, 0, 0, - 1337, 1397, 1346, 1384, 1332, 1371, 1290, 1357, 1409, 1319, - 1367, 1410, 322, 247, 324, 202, 410, 495, 285, 0, - 0, 0, 0, 0, 713, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 348, 357, 356, 337, 338, 340, 342, 347, 354, - 360, 1315, 1364, 602, 1404, 1316, 1366, 264, 320, 271, - 263, 575, 1415, 1396, 1279, 1345, 1403, 1340, 0, 0, - 228, 1406, 1339, 0, 1369, 0, 1421, 1274, 1360, 0, - 1277, 1281, 1417, 1401, 1310, 274, 0, 0, 0, 0, - 0, 0, 0, 1336, 1347, 1381, 1385, 1330, 0, 0, - 0, 0, 0, 0, 3168, 0, 1308, 0, 1356, 0, - 0, 0, 1286, 1278, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1334, 0, 0, 0, - 0, 1289, 0, 1309, 1382, 0, 1272, 296, 1283, 399, - 256, 0, 450, 1389, 1400, 1331, 620, 1402, 1329, 1328, - 1376, 1287, 1395, 1322, 362, 1285, 329, 197, 224, 0, - 1320, 409, 458, 470, 1394, 1305, 1314, 252, 1312, 468, - 423, 597, 232, 283, 455, 429, 466, 437, 286, 1355, - 1374, 467, 369, 580, 447, 594, 621, 622, 262, 403, - 607, 517, 615, 639, 225, 259, 417, 502, 600, 491, - 394, 576, 577, 328, 490, 294, 201, 366, 627, 223, - 476, 368, 241, 230, 582, 604, 298, 288, 453, 634, - 212, 512, 592, 238, 480, 0, 0, 642, 246, 501, - 214, 589, 500, 390, 325, 326, 213, 0, 454, 267, - 292, 0, 0, 257, 412, 584, 585, 255, 643, 227, - 614, 219, 1284, 613, 405, 579, 590, 391, 380, 218, - 588, 389, 379, 333, 352, 353, 279, 306, 444, 372, - 445, 305, 307, 401, 400, 402, 206, 601, 0, 207, - 0, 496, 603, 644, 449, 211, 233, 234, 236, 1300, - 278, 282, 290, 293, 302, 303, 312, 364, 416, 443, - 439, 448, 1390, 574, 595, 608, 619, 625, 626, 628, - 629, 630, 631, 632, 635, 633, 404, 310, 492, 332, - 370, 1379, 1420, 422, 469, 239, 599, 493, 199, 1294, - 1299, 1292, 0, 253, 254, 1361, 570, 1295, 1293, 1350, - 1351, 1296, 1411, 1412, 1413, 1398, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 659, 660, 661, 662, 640, 503, 509, 504, 505, 506, - 507, 508, 0, 510, 1383, 1288, 0, 1297, 1298, 395, - 1392, 586, 587, 663, 381, 483, 596, 334, 346, 349, - 339, 358, 0, 359, 335, 336, 341, 343, 344, 345, - 350, 351, 355, 361, 248, 209, 387, 396, 573, 311, - 215, 216, 217, 519, 520, 521, 522, 611, 612, 616, - 204, 459, 460, 461, 462, 291, 606, 308, 465, 464, - 330, 331, 376, 446, 535, 537, 548, 552, 554, 556, - 562, 565, 536, 538, 549, 553, 555, 557, 563, 566, - 525, 527, 529, 531, 544, 543, 540, 568, 569, 546, - 551, 530, 542, 547, 560, 567, 564, 524, 528, 532, - 541, 559, 558, 539, 550, 561, 545, 533, 526, 534, - 1354, 196, 220, 365, 1416, 451, 287, 641, 610, 481, - 605, 205, 222, 1291, 261, 1303, 1311, 0, 1317, 1325, - 1326, 1338, 1341, 1342, 1343, 1344, 1362, 1363, 1365, 1373, - 1375, 1378, 1380, 1387, 1399, 1419, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 309, 317, - 318, 321, 327, 377, 383, 384, 385, 386, 406, 407, - 408, 411, 414, 415, 418, 420, 421, 424, 428, 432, - 433, 434, 436, 438, 440, 452, 457, 471, 472, 473, - 474, 475, 478, 479, 485, 486, 487, 488, 489, 497, - 498, 511, 581, 583, 598, 617, 623, 477, 300, 301, - 441, 442, 313, 314, 637, 638, 299, 593, 624, 591, - 636, 618, 435, 375, 1353, 1359, 378, 280, 304, 319, - 1368, 609, 499, 226, 463, 289, 250, 1386, 1388, 210, - 245, 229, 258, 273, 276, 323, 388, 397, 426, 431, - 295, 270, 243, 456, 240, 482, 514, 515, 516, 518, - 392, 265, 430, 1349, 1377, 373, 571, 572, 315, 393, - 0, 0, 0, 0, 1405, 1391, 523, 0, 1333, 1408, - 1302, 1321, 1418, 1324, 1327, 1370, 1280, 1348, 413, 1318, - 1273, 1306, 1275, 1313, 1276, 1304, 1335, 269, 1301, 1393, - 1352, 1407, 363, 266, 1282, 1307, 427, 1323, 203, 1372, - 484, 251, 374, 371, 578, 281, 272, 268, 249, 316, - 382, 425, 513, 419, 1414, 367, 1358, 0, 494, 398, - 0, 0, 0, 1337, 1397, 1346, 1384, 1332, 1371, 1290, - 1357, 1409, 1319, 1367, 1410, 322, 247, 324, 202, 410, - 495, 285, 0, 0, 0, 0, 0, 946, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 348, 357, 356, 337, 338, 340, - 342, 347, 354, 360, 1315, 1364, 602, 1404, 1316, 1366, - 264, 320, 271, 263, 575, 1415, 1396, 1279, 1345, 1403, - 1340, 0, 0, 228, 1406, 1339, 0, 1369, 0, 1421, - 1274, 1360, 0, 1277, 1281, 1417, 1401, 1310, 274, 0, - 0, 0, 0, 0, 0, 0, 1336, 1347, 1381, 1385, - 1330, 0, 0, 0, 0, 0, 0, 2373, 0, 1308, - 0, 1356, 0, 0, 0, 1286, 1278, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1334, - 0, 0, 0, 0, 1289, 0, 1309, 1382, 0, 1272, - 296, 1283, 399, 256, 0, 450, 1389, 1400, 1331, 620, - 1402, 1329, 1328, 1376, 1287, 1395, 1322, 362, 1285, 329, - 197, 224, 0, 1320, 409, 458, 470, 1394, 1305, 1314, - 252, 1312, 468, 423, 597, 232, 283, 455, 429, 466, - 437, 286, 1355, 1374, 467, 369, 580, 447, 594, 621, - 622, 262, 403, 607, 517, 615, 639, 225, 259, 417, - 502, 600, 491, 394, 576, 577, 328, 490, 294, 201, - 366, 627, 223, 476, 368, 241, 230, 582, 604, 298, - 288, 453, 634, 212, 512, 592, 238, 480, 0, 0, - 642, 246, 501, 214, 589, 500, 390, 325, 326, 213, - 0, 454, 267, 292, 0, 0, 257, 412, 584, 585, - 255, 643, 227, 614, 219, 1284, 613, 405, 579, 590, - 391, 380, 218, 588, 389, 379, 333, 352, 353, 279, - 306, 444, 372, 445, 305, 307, 401, 400, 402, 206, - 601, 0, 207, 0, 496, 603, 644, 449, 211, 233, - 234, 236, 1300, 278, 282, 290, 293, 302, 303, 312, - 364, 416, 443, 439, 448, 1390, 574, 595, 608, 619, - 625, 626, 628, 629, 630, 631, 632, 635, 633, 404, - 310, 492, 332, 370, 1379, 1420, 422, 469, 239, 599, - 493, 199, 1294, 1299, 1292, 0, 253, 254, 1361, 570, - 1295, 1293, 1350, 1351, 1296, 1411, 1412, 1413, 1398, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 659, 660, 661, 662, 640, 503, 509, - 504, 505, 506, 507, 508, 0, 510, 1383, 1288, 0, - 1297, 1298, 395, 1392, 586, 587, 663, 381, 483, 596, - 334, 346, 349, 339, 358, 0, 359, 335, 336, 341, - 343, 344, 345, 350, 351, 355, 361, 248, 209, 387, - 396, 573, 311, 215, 216, 217, 519, 520, 521, 522, - 611, 612, 616, 204, 459, 460, 461, 462, 291, 606, - 308, 465, 464, 330, 331, 376, 446, 535, 537, 548, - 552, 554, 556, 562, 565, 536, 538, 549, 553, 555, - 557, 563, 566, 525, 527, 529, 531, 544, 543, 540, - 568, 569, 546, 551, 530, 542, 547, 560, 567, 564, - 524, 528, 532, 541, 559, 558, 539, 550, 561, 545, - 533, 526, 534, 1354, 196, 220, 365, 1416, 451, 287, - 641, 610, 481, 605, 205, 222, 1291, 261, 1303, 1311, - 0, 1317, 1325, 1326, 1338, 1341, 1342, 1343, 1344, 1362, - 1363, 1365, 1373, 1375, 1378, 1380, 1387, 1399, 1419, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 309, 317, 318, 321, 327, 377, 383, 384, 385, - 386, 406, 407, 408, 411, 414, 415, 418, 420, 421, - 424, 428, 432, 433, 434, 436, 438, 440, 452, 457, - 471, 472, 473, 474, 475, 478, 479, 485, 486, 487, - 488, 489, 497, 498, 511, 581, 583, 598, 617, 623, - 477, 300, 301, 441, 442, 313, 314, 637, 638, 299, - 593, 624, 591, 636, 618, 435, 375, 1353, 1359, 378, - 280, 304, 319, 1368, 609, 499, 226, 463, 289, 250, - 1386, 1388, 210, 245, 229, 258, 273, 276, 323, 388, - 397, 426, 431, 295, 270, 243, 456, 240, 482, 514, - 515, 516, 518, 392, 265, 430, 1349, 1377, 373, 571, - 572, 315, 393, 0, 0, 0, 0, 1405, 1391, 523, - 0, 1333, 1408, 1302, 1321, 1418, 1324, 1327, 1370, 1280, - 1348, 413, 1318, 1273, 1306, 1275, 1313, 1276, 1304, 1335, - 269, 1301, 1393, 1352, 1407, 363, 266, 1282, 1307, 427, - 1323, 203, 1372, 484, 251, 374, 371, 578, 281, 272, - 268, 249, 316, 382, 425, 513, 419, 1414, 367, 1358, - 0, 494, 398, 0, 0, 0, 1337, 1397, 1346, 1384, - 1332, 1371, 1290, 1357, 1409, 1319, 1367, 1410, 322, 247, - 324, 202, 410, 495, 285, 0, 95, 0, 0, 0, - 713, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 348, 357, 356, - 337, 338, 340, 342, 347, 354, 360, 1315, 1364, 602, - 1404, 1316, 1366, 264, 320, 271, 263, 575, 1415, 1396, - 1279, 1345, 1403, 1340, 0, 0, 228, 1406, 1339, 0, - 1369, 0, 1421, 1274, 1360, 0, 1277, 1281, 1417, 1401, - 1310, 274, 0, 0, 0, 0, 0, 0, 0, 1336, - 1347, 1381, 1385, 1330, 0, 0, 0, 0, 0, 0, - 0, 0, 1308, 0, 1356, 0, 0, 0, 1286, 1278, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1334, 0, 0, 0, 0, 1289, 0, 1309, - 1382, 0, 1272, 296, 1283, 399, 256, 0, 450, 1389, - 1400, 1331, 620, 1402, 1329, 1328, 1376, 1287, 1395, 1322, - 362, 1285, 329, 197, 224, 0, 1320, 409, 458, 470, - 1394, 1305, 1314, 252, 1312, 468, 423, 597, 232, 283, - 455, 429, 466, 437, 286, 1355, 1374, 467, 369, 580, - 447, 594, 621, 622, 262, 403, 607, 517, 615, 639, - 225, 259, 417, 502, 600, 491, 394, 576, 577, 328, - 490, 294, 201, 366, 627, 223, 476, 368, 241, 230, - 582, 604, 298, 288, 453, 634, 212, 512, 592, 238, - 480, 0, 0, 642, 246, 501, 214, 589, 500, 390, - 325, 326, 213, 0, 454, 267, 292, 0, 0, 257, - 412, 584, 585, 255, 643, 227, 614, 219, 1284, 613, - 405, 579, 590, 391, 380, 218, 588, 389, 379, 333, - 352, 353, 279, 306, 444, 372, 445, 305, 307, 401, - 400, 402, 206, 601, 0, 207, 0, 496, 603, 644, - 449, 211, 233, 234, 236, 1300, 278, 282, 290, 293, - 302, 303, 312, 364, 416, 443, 439, 448, 1390, 574, - 595, 608, 619, 625, 626, 628, 629, 630, 631, 632, - 635, 633, 404, 310, 492, 332, 370, 1379, 1420, 422, - 469, 239, 599, 493, 199, 1294, 1299, 1292, 0, 253, - 254, 1361, 570, 1295, 1293, 1350, 1351, 1296, 1411, 1412, - 1413, 1398, 645, 646, 647, 648, 649, 650, 651, 652, + 0, 0, 0, 0, 1336, 0, 0, 0, 0, 1291, + 0, 1311, 1384, 0, 1274, 297, 1285, 400, 257, 0, + 451, 1391, 1402, 1333, 622, 1404, 1331, 1330, 1378, 1289, + 1397, 1324, 363, 1287, 330, 197, 225, 0, 1322, 410, + 459, 471, 1396, 1307, 1316, 253, 1314, 469, 424, 599, + 233, 284, 456, 430, 467, 438, 287, 1357, 1376, 468, + 370, 582, 448, 596, 623, 624, 263, 404, 609, 519, + 617, 641, 226, 260, 418, 504, 602, 492, 395, 578, + 579, 329, 491, 295, 201, 367, 629, 224, 477, 369, + 242, 231, 584, 606, 299, 289, 454, 636, 213, 514, + 594, 239, 481, 0, 0, 644, 247, 502, 215, 591, + 501, 391, 326, 327, 214, 0, 455, 268, 293, 0, + 0, 258, 413, 586, 587, 256, 645, 228, 616, 220, + 1286, 615, 406, 581, 592, 392, 381, 219, 590, 390, + 380, 334, 353, 354, 280, 307, 445, 373, 446, 306, + 308, 402, 401, 403, 207, 603, 0, 208, 0, 497, + 605, 646, 450, 212, 234, 235, 237, 1302, 279, 283, + 291, 294, 303, 304, 313, 365, 417, 444, 440, 449, + 1392, 576, 597, 610, 621, 627, 628, 630, 631, 632, + 633, 634, 637, 635, 405, 311, 493, 333, 371, 1381, + 1422, 423, 470, 240, 601, 494, 199, 1296, 1301, 1294, + 0, 254, 255, 1363, 572, 1297, 1295, 1352, 1353, 1298, + 1413, 1414, 1415, 1400, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, - 640, 503, 509, 504, 505, 506, 507, 508, 0, 510, - 1383, 1288, 0, 1297, 1298, 395, 1392, 586, 587, 663, - 381, 483, 596, 334, 346, 349, 339, 358, 0, 359, - 335, 336, 341, 343, 344, 345, 350, 351, 355, 361, - 248, 209, 387, 396, 573, 311, 215, 216, 217, 519, - 520, 521, 522, 611, 612, 616, 204, 459, 460, 461, - 462, 291, 606, 308, 465, 464, 330, 331, 376, 446, - 535, 537, 548, 552, 554, 556, 562, 565, 536, 538, - 549, 553, 555, 557, 563, 566, 525, 527, 529, 531, - 544, 543, 540, 568, 569, 546, 551, 530, 542, 547, - 560, 567, 564, 524, 528, 532, 541, 559, 558, 539, - 550, 561, 545, 533, 526, 534, 1354, 196, 220, 365, - 1416, 451, 287, 641, 610, 481, 605, 205, 222, 1291, - 261, 1303, 1311, 0, 1317, 1325, 1326, 1338, 1341, 1342, - 1343, 1344, 1362, 1363, 1365, 1373, 1375, 1378, 1380, 1387, - 1399, 1419, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 309, 317, 318, 321, 327, 377, - 383, 384, 385, 386, 406, 407, 408, 411, 414, 415, - 418, 420, 421, 424, 428, 432, 433, 434, 436, 438, - 440, 452, 457, 471, 472, 473, 474, 475, 478, 479, - 485, 486, 487, 488, 489, 497, 498, 511, 581, 583, - 598, 617, 623, 477, 300, 301, 441, 442, 313, 314, - 637, 638, 299, 593, 624, 591, 636, 618, 435, 375, - 1353, 1359, 378, 280, 304, 319, 1368, 609, 499, 226, - 463, 289, 250, 1386, 1388, 210, 245, 229, 258, 273, - 276, 323, 388, 397, 426, 431, 295, 270, 243, 456, - 240, 482, 514, 515, 516, 518, 392, 265, 430, 1349, - 1377, 373, 571, 572, 315, 393, 0, 0, 0, 0, - 1405, 1391, 523, 0, 1333, 1408, 1302, 1321, 1418, 1324, - 1327, 1370, 1280, 1348, 413, 1318, 1273, 1306, 1275, 1313, - 1276, 1304, 1335, 269, 1301, 1393, 1352, 1407, 363, 266, - 1282, 1307, 427, 1323, 203, 1372, 484, 251, 374, 371, - 578, 281, 272, 268, 249, 316, 382, 425, 513, 419, - 1414, 367, 1358, 0, 494, 398, 0, 0, 0, 1337, - 1397, 1346, 1384, 1332, 1371, 1290, 1357, 1409, 1319, 1367, - 1410, 322, 247, 324, 202, 410, 495, 285, 0, 0, - 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 348, 357, 356, 337, 338, 340, 342, 347, 354, 360, - 1315, 1364, 602, 1404, 1316, 1366, 264, 320, 271, 263, - 575, 1415, 1396, 1279, 1345, 1403, 1340, 0, 0, 228, - 1406, 1339, 0, 1369, 0, 1421, 1274, 1360, 0, 1277, - 1281, 1417, 1401, 1310, 274, 0, 0, 0, 0, 0, - 0, 0, 1336, 1347, 1381, 1385, 1330, 0, 0, 0, - 0, 0, 0, 0, 0, 1308, 0, 1356, 0, 0, - 0, 1286, 1278, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1334, 0, 0, 0, 0, - 1289, 0, 1309, 1382, 0, 1272, 296, 1283, 399, 256, - 0, 450, 1389, 1400, 1331, 620, 1402, 1329, 1328, 1376, - 1287, 1395, 1322, 362, 1285, 329, 197, 224, 0, 1320, - 409, 458, 470, 1394, 1305, 1314, 252, 1312, 468, 423, - 597, 232, 283, 455, 429, 466, 437, 286, 1355, 1374, - 467, 369, 580, 447, 594, 621, 622, 262, 403, 607, - 517, 615, 639, 225, 259, 417, 502, 600, 491, 394, - 576, 577, 328, 490, 294, 201, 366, 627, 223, 476, - 368, 241, 230, 582, 604, 298, 288, 453, 634, 212, - 512, 592, 238, 480, 0, 0, 642, 246, 501, 214, - 589, 500, 390, 325, 326, 213, 0, 454, 267, 292, - 0, 0, 257, 412, 584, 585, 255, 643, 227, 614, - 219, 1284, 613, 405, 579, 590, 391, 380, 218, 588, - 389, 379, 333, 352, 353, 279, 306, 444, 372, 445, - 305, 307, 401, 400, 402, 206, 601, 0, 207, 0, - 496, 603, 644, 449, 211, 233, 234, 236, 1300, 278, - 282, 290, 293, 302, 303, 312, 364, 416, 443, 439, - 448, 1390, 574, 595, 608, 619, 625, 626, 628, 629, - 630, 631, 632, 635, 633, 404, 310, 492, 332, 370, - 1379, 1420, 422, 469, 239, 599, 493, 199, 1294, 1299, - 1292, 0, 253, 254, 1361, 570, 1295, 1293, 1350, 1351, - 1296, 1411, 1412, 1413, 1398, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, - 660, 661, 662, 640, 503, 509, 504, 505, 506, 507, - 508, 0, 510, 1383, 1288, 0, 1297, 1298, 395, 1392, - 586, 587, 663, 381, 483, 596, 334, 346, 349, 339, - 358, 0, 359, 335, 336, 341, 343, 344, 345, 350, - 351, 355, 361, 248, 209, 387, 396, 573, 311, 215, - 216, 217, 519, 520, 521, 522, 611, 612, 616, 204, - 459, 460, 461, 462, 291, 606, 308, 465, 464, 330, - 331, 376, 446, 535, 537, 548, 552, 554, 556, 562, - 565, 536, 538, 549, 553, 555, 557, 563, 566, 525, - 527, 529, 531, 544, 543, 540, 568, 569, 546, 551, - 530, 542, 547, 560, 567, 564, 524, 528, 532, 541, - 559, 558, 539, 550, 561, 545, 533, 526, 534, 1354, - 196, 220, 365, 1416, 451, 287, 641, 610, 481, 605, - 205, 222, 1291, 261, 1303, 1311, 0, 1317, 1325, 1326, - 1338, 1341, 1342, 1343, 1344, 1362, 1363, 1365, 1373, 1375, - 1378, 1380, 1387, 1399, 1419, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 309, 317, 318, - 321, 327, 377, 383, 384, 385, 386, 406, 407, 408, - 411, 414, 415, 418, 420, 421, 424, 428, 432, 433, - 434, 436, 438, 440, 452, 457, 471, 472, 473, 474, - 475, 478, 479, 485, 486, 487, 488, 489, 497, 498, - 511, 581, 583, 598, 617, 623, 477, 300, 301, 441, - 442, 313, 314, 637, 638, 299, 593, 624, 591, 636, - 618, 435, 375, 1353, 1359, 378, 280, 304, 319, 1368, - 609, 499, 226, 463, 289, 250, 1386, 1388, 210, 245, - 229, 258, 273, 276, 323, 388, 397, 426, 431, 295, - 270, 243, 456, 240, 482, 514, 515, 516, 518, 392, - 265, 430, 1349, 1377, 373, 571, 572, 315, 393, 0, - 0, 0, 0, 1405, 1391, 523, 0, 1333, 1408, 1302, - 1321, 1418, 1324, 1327, 1370, 1280, 1348, 413, 1318, 1273, - 1306, 1275, 1313, 1276, 1304, 1335, 269, 1301, 1393, 1352, - 1407, 363, 266, 1282, 1307, 427, 1323, 203, 1372, 484, - 251, 374, 371, 578, 281, 272, 268, 249, 316, 382, - 425, 513, 419, 1414, 367, 1358, 0, 494, 398, 0, - 0, 0, 1337, 1397, 1346, 1384, 1332, 1371, 1290, 1357, - 1409, 1319, 1367, 1410, 322, 247, 324, 202, 410, 495, - 285, 0, 0, 0, 0, 0, 713, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 348, 357, 356, 337, 338, 340, 342, - 347, 354, 360, 1315, 1364, 602, 1404, 1316, 1366, 264, - 320, 271, 263, 575, 1415, 1396, 1279, 1345, 1403, 1340, - 0, 0, 228, 1406, 1339, 0, 1369, 0, 1421, 1274, - 1360, 0, 1277, 1281, 1417, 1401, 1310, 274, 0, 0, - 0, 0, 0, 0, 0, 1336, 1347, 1381, 1385, 1330, - 0, 0, 0, 0, 0, 0, 0, 0, 1308, 0, - 1356, 0, 0, 0, 1286, 1278, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1334, 0, - 0, 0, 0, 1289, 0, 1309, 1382, 0, 1272, 296, - 1283, 399, 256, 0, 450, 1389, 1400, 1331, 620, 1402, - 1329, 1328, 1376, 1287, 1395, 1322, 362, 1285, 329, 197, - 224, 0, 1320, 409, 458, 470, 1394, 1305, 1314, 252, - 1312, 468, 423, 597, 232, 283, 455, 429, 466, 437, - 286, 1355, 1374, 467, 369, 580, 447, 594, 621, 622, - 262, 403, 607, 517, 615, 639, 225, 259, 417, 502, - 600, 491, 394, 576, 577, 328, 490, 294, 201, 366, - 627, 223, 476, 368, 241, 230, 582, 604, 298, 288, - 453, 634, 212, 512, 592, 238, 480, 0, 0, 642, - 246, 501, 214, 589, 500, 390, 325, 326, 213, 0, - 454, 267, 292, 0, 0, 257, 412, 584, 585, 255, - 643, 227, 614, 219, 1284, 613, 405, 579, 590, 391, - 380, 218, 588, 389, 379, 333, 352, 353, 279, 306, - 444, 372, 445, 305, 307, 401, 400, 402, 206, 601, - 0, 207, 0, 496, 603, 644, 449, 211, 233, 234, - 236, 1300, 278, 282, 290, 293, 302, 303, 312, 364, - 416, 443, 439, 448, 1390, 574, 595, 608, 619, 625, - 626, 628, 629, 630, 631, 632, 635, 633, 404, 310, - 492, 332, 370, 1379, 1420, 422, 469, 239, 599, 493, - 199, 1294, 1299, 1292, 0, 253, 254, 1361, 570, 1295, - 1293, 1350, 1351, 1296, 1411, 1412, 1413, 1398, 645, 646, + 663, 664, 642, 505, 511, 506, 507, 508, 509, 510, + 0, 512, 1385, 1290, 0, 1299, 1300, 396, 1394, 588, + 589, 665, 382, 484, 598, 335, 347, 350, 340, 359, + 0, 360, 336, 337, 342, 344, 345, 346, 351, 352, + 356, 362, 249, 210, 388, 397, 575, 312, 216, 217, + 218, 521, 522, 523, 524, 613, 614, 618, 205, 460, + 461, 462, 463, 292, 608, 309, 466, 465, 331, 332, + 377, 447, 537, 539, 550, 554, 556, 558, 564, 567, + 538, 540, 551, 555, 557, 559, 565, 568, 527, 529, + 531, 533, 546, 545, 542, 570, 571, 548, 553, 532, + 544, 549, 562, 569, 566, 526, 530, 534, 543, 561, + 560, 541, 552, 563, 547, 535, 528, 536, 1356, 196, + 221, 366, 1418, 452, 288, 643, 612, 482, 607, 206, + 223, 1293, 262, 1305, 1313, 0, 1319, 1327, 1328, 1340, + 1343, 1344, 1345, 1346, 1364, 1365, 1367, 1375, 1377, 1380, + 1382, 1389, 1401, 1421, 198, 200, 209, 222, 232, 236, + 243, 261, 276, 278, 285, 298, 310, 318, 319, 322, + 328, 378, 384, 385, 386, 387, 407, 408, 409, 412, + 415, 416, 419, 421, 422, 425, 429, 433, 434, 435, + 437, 439, 441, 453, 458, 472, 473, 474, 475, 476, + 479, 480, 486, 487, 488, 489, 490, 498, 499, 513, + 583, 585, 600, 619, 625, 478, 301, 302, 442, 443, + 314, 315, 639, 640, 300, 595, 626, 593, 638, 620, + 436, 376, 1355, 1361, 379, 281, 305, 320, 1370, 611, + 500, 227, 464, 290, 251, 1388, 1390, 211, 246, 230, + 259, 274, 277, 324, 389, 398, 427, 432, 296, 271, + 244, 457, 241, 483, 516, 517, 518, 520, 393, 266, + 431, 1351, 1379, 374, 573, 574, 316, 394, 0, 0, + 0, 0, 0, 1407, 1393, 525, 0, 1335, 1410, 1304, + 1323, 1420, 1326, 1329, 1372, 1282, 1350, 414, 1320, 1308, + 1277, 1315, 1278, 1306, 1337, 270, 1303, 1395, 1354, 1409, + 364, 267, 1284, 1275, 204, 503, 1309, 428, 1325, 203, + 1374, 485, 252, 375, 372, 580, 282, 273, 269, 250, + 317, 383, 426, 515, 420, 1416, 368, 1360, 0, 495, + 399, 0, 0, 0, 1339, 1399, 1348, 1386, 1334, 1373, + 1292, 1359, 1411, 1321, 1369, 1412, 323, 248, 325, 202, + 411, 496, 286, 0, 0, 0, 0, 0, 194, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, + 0, 245, 0, 0, 0, 349, 358, 357, 338, 339, + 341, 343, 348, 355, 361, 1317, 1366, 604, 1406, 1318, + 1368, 265, 321, 272, 264, 577, 1417, 1398, 1281, 1347, + 1405, 1342, 0, 0, 229, 1408, 1341, 0, 1371, 0, + 1423, 1276, 1362, 0, 1279, 1283, 1419, 1403, 1312, 275, + 0, 0, 0, 0, 0, 0, 0, 1338, 1349, 1383, + 1387, 1332, 0, 0, 0, 0, 0, 0, 3216, 0, + 1310, 0, 1358, 0, 0, 0, 1288, 1280, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1336, 0, 0, 0, 0, 1291, 0, 1311, 1384, 0, + 1274, 297, 1285, 400, 257, 0, 451, 1391, 1402, 1333, + 622, 1404, 1331, 1330, 1378, 1289, 1397, 1324, 363, 1287, + 330, 197, 225, 0, 1322, 410, 459, 471, 1396, 1307, + 1316, 253, 1314, 469, 424, 599, 233, 284, 456, 430, + 467, 438, 287, 1357, 1376, 468, 370, 582, 448, 596, + 623, 624, 263, 404, 609, 519, 617, 641, 226, 260, + 418, 504, 602, 492, 395, 578, 579, 329, 491, 295, + 201, 367, 629, 224, 477, 369, 242, 231, 584, 606, + 299, 289, 454, 636, 213, 514, 594, 239, 481, 0, + 0, 644, 247, 502, 215, 591, 501, 391, 326, 327, + 214, 0, 455, 268, 293, 0, 0, 258, 413, 586, + 587, 256, 645, 228, 616, 220, 1286, 615, 406, 581, + 592, 392, 381, 219, 590, 390, 380, 334, 353, 354, + 280, 307, 445, 373, 446, 306, 308, 402, 401, 403, + 207, 603, 0, 208, 0, 497, 605, 646, 450, 212, + 234, 235, 237, 1302, 279, 283, 291, 294, 303, 304, + 313, 365, 417, 444, 440, 449, 1392, 576, 597, 610, + 621, 627, 628, 630, 631, 632, 633, 634, 637, 635, + 405, 311, 493, 333, 371, 1381, 1422, 423, 470, 240, + 601, 494, 199, 1296, 1301, 1294, 0, 254, 255, 1363, + 572, 1297, 1295, 1352, 1353, 1298, 1413, 1414, 1415, 1400, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 659, 660, 661, 662, 640, 503, 509, 504, - 505, 506, 507, 508, 0, 510, 1383, 1288, 0, 1297, - 1298, 395, 1392, 586, 587, 663, 381, 483, 596, 334, - 346, 349, 339, 358, 0, 359, 335, 336, 341, 343, - 344, 345, 350, 351, 355, 361, 248, 209, 387, 396, - 573, 311, 215, 216, 217, 519, 520, 521, 522, 611, - 612, 616, 204, 459, 460, 461, 462, 291, 606, 308, - 465, 464, 330, 331, 376, 446, 535, 537, 548, 552, - 554, 556, 562, 565, 536, 538, 549, 553, 555, 557, - 563, 566, 525, 527, 529, 531, 544, 543, 540, 568, - 569, 546, 551, 530, 542, 547, 560, 567, 564, 524, - 528, 532, 541, 559, 558, 539, 550, 561, 545, 533, - 526, 534, 1354, 196, 220, 365, 1416, 451, 287, 641, - 610, 481, 605, 205, 222, 1291, 261, 1303, 1311, 0, - 1317, 1325, 1326, 1338, 1341, 1342, 1343, 1344, 1362, 1363, - 1365, 1373, 1375, 1378, 1380, 1387, 1399, 1419, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 309, 317, 318, 321, 327, 377, 383, 384, 385, 386, - 406, 407, 408, 411, 414, 415, 418, 420, 421, 424, - 428, 432, 433, 434, 436, 438, 440, 452, 457, 471, - 472, 473, 474, 475, 478, 479, 485, 486, 487, 488, - 489, 497, 498, 511, 581, 583, 598, 617, 623, 477, - 300, 301, 441, 442, 313, 314, 637, 638, 299, 593, - 624, 591, 636, 618, 435, 375, 1353, 1359, 378, 280, - 304, 319, 1368, 609, 499, 226, 463, 289, 250, 1386, - 1388, 210, 245, 229, 258, 273, 276, 323, 388, 397, - 426, 431, 295, 270, 243, 456, 240, 482, 514, 515, - 516, 518, 392, 265, 430, 1349, 1377, 373, 571, 572, - 315, 393, 0, 0, 0, 0, 1405, 1391, 523, 0, - 1333, 1408, 1302, 1321, 1418, 1324, 1327, 1370, 1280, 1348, - 413, 1318, 1273, 1306, 1275, 1313, 1276, 1304, 1335, 269, - 1301, 1393, 1352, 1407, 363, 266, 1282, 1307, 427, 1323, - 203, 1372, 484, 251, 374, 371, 578, 281, 272, 268, - 249, 316, 382, 425, 513, 419, 1414, 367, 1358, 0, - 494, 398, 0, 0, 0, 1337, 1397, 1346, 1384, 1332, - 1371, 1290, 1357, 1409, 1319, 1367, 1410, 322, 247, 324, - 202, 410, 495, 285, 0, 0, 0, 0, 0, 946, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 348, 357, 356, 337, - 338, 340, 342, 347, 354, 360, 1315, 1364, 602, 1404, - 1316, 1366, 264, 320, 271, 263, 575, 1415, 1396, 1279, - 1345, 1403, 1340, 0, 0, 228, 1406, 1339, 0, 1369, - 0, 1421, 1274, 1360, 0, 1277, 1281, 1417, 1401, 1310, - 274, 0, 0, 0, 0, 0, 0, 0, 1336, 1347, - 1381, 1385, 1330, 0, 0, 0, 0, 0, 0, 0, - 0, 1308, 0, 1356, 0, 0, 0, 1286, 1278, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1334, 0, 0, 0, 0, 1289, 0, 1309, 1382, - 0, 1272, 296, 1283, 399, 256, 0, 450, 1389, 1400, - 1331, 620, 1402, 1329, 1328, 1376, 1287, 1395, 1322, 362, - 1285, 329, 197, 224, 0, 1320, 409, 458, 470, 1394, - 1305, 1314, 252, 1312, 468, 423, 597, 232, 283, 455, - 429, 466, 437, 286, 1355, 1374, 467, 369, 580, 447, - 594, 621, 622, 262, 403, 607, 517, 615, 639, 225, - 259, 417, 502, 600, 491, 394, 576, 577, 328, 490, - 294, 201, 366, 627, 223, 476, 368, 241, 230, 582, - 604, 298, 288, 453, 634, 212, 512, 592, 238, 480, - 0, 0, 642, 246, 501, 214, 589, 500, 390, 325, - 326, 213, 0, 454, 267, 292, 0, 0, 257, 412, - 584, 585, 255, 643, 227, 614, 219, 1284, 613, 405, - 579, 590, 391, 380, 218, 588, 389, 379, 333, 352, - 353, 279, 306, 444, 372, 445, 305, 307, 401, 400, - 402, 206, 601, 0, 207, 0, 496, 603, 644, 449, - 211, 233, 234, 236, 1300, 278, 282, 290, 293, 302, - 303, 312, 364, 416, 443, 439, 448, 1390, 574, 595, - 608, 619, 625, 626, 628, 629, 630, 631, 632, 635, - 633, 404, 310, 492, 332, 370, 1379, 1420, 422, 469, - 239, 599, 493, 199, 1294, 1299, 1292, 0, 253, 254, - 1361, 570, 1295, 1293, 1350, 1351, 1296, 1411, 1412, 1413, - 1398, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 659, 660, 661, 662, 640, - 503, 509, 504, 505, 506, 507, 508, 0, 510, 1383, - 1288, 0, 1297, 1298, 395, 1392, 586, 587, 663, 381, - 483, 596, 334, 346, 349, 339, 358, 0, 359, 335, - 336, 341, 343, 344, 345, 350, 351, 355, 361, 248, - 209, 387, 396, 573, 311, 215, 216, 217, 519, 520, - 521, 522, 611, 612, 616, 204, 459, 460, 461, 462, - 291, 606, 308, 465, 464, 330, 331, 376, 446, 535, - 537, 548, 552, 554, 556, 562, 565, 536, 538, 549, - 553, 555, 557, 563, 566, 525, 527, 529, 531, 544, - 543, 540, 568, 569, 546, 551, 530, 542, 547, 560, - 567, 564, 524, 528, 532, 541, 559, 558, 539, 550, - 561, 545, 533, 526, 534, 1354, 196, 220, 365, 1416, - 451, 287, 641, 610, 481, 605, 205, 222, 1291, 261, - 1303, 1311, 0, 1317, 1325, 1326, 1338, 1341, 1342, 1343, - 1344, 1362, 1363, 1365, 1373, 1375, 1378, 1380, 1387, 1399, - 1419, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 309, 317, 318, 321, 327, 377, 383, - 384, 385, 386, 406, 407, 408, 411, 414, 415, 418, - 420, 421, 424, 428, 432, 433, 434, 436, 438, 440, - 452, 457, 471, 472, 473, 474, 475, 478, 479, 485, - 486, 487, 488, 489, 497, 498, 511, 581, 583, 598, - 617, 623, 477, 300, 301, 441, 442, 313, 314, 637, - 638, 299, 593, 624, 591, 636, 618, 435, 375, 1353, - 1359, 378, 280, 304, 319, 1368, 609, 499, 226, 463, - 289, 250, 1386, 1388, 210, 245, 229, 258, 273, 276, - 323, 388, 397, 426, 431, 295, 270, 243, 456, 240, - 482, 514, 515, 516, 518, 392, 265, 430, 1349, 1377, - 373, 571, 572, 315, 393, 0, 0, 0, 0, 0, - 0, 523, 0, 766, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 413, 0, 0, 0, 0, 753, 0, - 0, 0, 269, 758, 0, 0, 0, 363, 266, 0, - 0, 427, 0, 203, 0, 484, 251, 374, 371, 578, - 281, 272, 268, 249, 316, 382, 425, 513, 419, 765, - 367, 0, 0, 494, 398, 0, 0, 0, 0, 0, - 760, 761, 0, 0, 0, 0, 0, 0, 0, 0, - 322, 247, 324, 202, 410, 495, 285, 0, 95, 0, - 0, 1010, 946, 737, 912, 950, 1011, 963, 964, 965, - 951, 0, 237, 952, 953, 244, 954, 0, 911, 796, - 798, 797, 861, 862, 863, 864, 865, 866, 867, 794, - 959, 602, 966, 967, 0, 264, 320, 271, 263, 575, - 0, 0, 2195, 2196, 2197, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 733, 750, 0, 764, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 747, 748, 0, 0, 0, 0, 906, 0, 749, 0, - 0, 757, 968, 969, 970, 971, 972, 973, 974, 975, - 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, - 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, - 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, - 1006, 1007, 1008, 1009, 759, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 399, 256, 0, - 450, 905, 0, 0, 620, 0, 0, 903, 0, 0, - 0, 0, 362, 0, 329, 197, 224, 0, 0, 409, - 458, 470, 0, 0, 0, 956, 0, 468, 423, 597, - 232, 283, 455, 429, 466, 437, 286, 0, 0, 467, - 369, 580, 447, 594, 621, 622, 262, 403, 607, 517, - 615, 639, 225, 259, 417, 502, 600, 491, 394, 576, - 577, 328, 490, 294, 201, 366, 627, 223, 476, 368, - 241, 230, 582, 604, 298, 288, 453, 634, 212, 512, - 592, 238, 480, 0, 0, 642, 246, 501, 214, 589, - 500, 390, 325, 326, 213, 0, 454, 267, 292, 0, - 0, 257, 412, 957, 958, 255, 643, 802, 614, 219, - 0, 613, 405, 579, 590, 391, 380, 218, 588, 389, - 379, 333, 810, 811, 279, 306, 887, 886, 885, 305, - 307, 883, 884, 882, 206, 601, 0, 207, 0, 496, - 603, 644, 449, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 302, 303, 312, 364, 416, 443, 439, 448, - 0, 574, 595, 608, 619, 625, 626, 628, 629, 630, - 631, 632, 635, 633, 404, 310, 492, 332, 370, 0, - 0, 422, 469, 239, 599, 493, 893, 915, 904, 770, - 771, 894, 895, 919, 896, 773, 774, 916, 917, 767, - 768, 772, 918, 920, 645, 646, 647, 648, 649, 650, + 657, 658, 659, 660, 661, 662, 663, 664, 642, 505, + 511, 506, 507, 508, 509, 510, 0, 512, 1385, 1290, + 0, 1299, 1300, 396, 1394, 588, 589, 665, 382, 484, + 598, 335, 347, 350, 340, 359, 0, 360, 336, 337, + 342, 344, 345, 346, 351, 352, 356, 362, 249, 210, + 388, 397, 575, 312, 216, 217, 218, 521, 522, 523, + 524, 613, 614, 618, 205, 460, 461, 462, 463, 292, + 608, 309, 466, 465, 331, 332, 377, 447, 537, 539, + 550, 554, 556, 558, 564, 567, 538, 540, 551, 555, + 557, 559, 565, 568, 527, 529, 531, 533, 546, 545, + 542, 570, 571, 548, 553, 532, 544, 549, 562, 569, + 566, 526, 530, 534, 543, 561, 560, 541, 552, 563, + 547, 535, 528, 536, 1356, 196, 221, 366, 1418, 452, + 288, 643, 612, 482, 607, 206, 223, 1293, 262, 1305, + 1313, 0, 1319, 1327, 1328, 1340, 1343, 1344, 1345, 1346, + 1364, 1365, 1367, 1375, 1377, 1380, 1382, 1389, 1401, 1421, + 198, 200, 209, 222, 232, 236, 243, 261, 276, 278, + 285, 298, 310, 318, 319, 322, 328, 378, 384, 385, + 386, 387, 407, 408, 409, 412, 415, 416, 419, 421, + 422, 425, 429, 433, 434, 435, 437, 439, 441, 453, + 458, 472, 473, 474, 475, 476, 479, 480, 486, 487, + 488, 489, 490, 498, 499, 513, 583, 585, 600, 619, + 625, 478, 301, 302, 442, 443, 314, 315, 639, 640, + 300, 595, 626, 593, 638, 620, 436, 376, 1355, 1361, + 379, 281, 305, 320, 1370, 611, 500, 227, 464, 290, + 251, 1388, 1390, 211, 246, 230, 259, 274, 277, 324, + 389, 398, 427, 432, 296, 271, 244, 457, 241, 483, + 516, 517, 518, 520, 393, 266, 431, 1351, 1379, 374, + 573, 574, 316, 394, 0, 0, 0, 0, 0, 1407, + 1393, 525, 0, 1335, 1410, 1304, 1323, 1420, 1326, 1329, + 1372, 1282, 1350, 414, 1320, 1308, 1277, 1315, 1278, 1306, + 1337, 270, 1303, 1395, 1354, 1409, 364, 267, 1284, 1275, + 204, 503, 1309, 428, 1325, 203, 1374, 485, 252, 375, + 372, 580, 282, 273, 269, 250, 317, 383, 426, 515, + 420, 1416, 368, 1360, 0, 495, 399, 0, 0, 0, + 1339, 1399, 1348, 1386, 1334, 1373, 1292, 1359, 1411, 1321, + 1369, 1412, 323, 248, 325, 202, 411, 496, 286, 0, + 0, 0, 0, 0, 715, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 238, 0, 0, 245, 0, 0, + 0, 349, 358, 357, 338, 339, 341, 343, 348, 355, + 361, 1317, 1366, 604, 1406, 1318, 1368, 265, 321, 272, + 264, 577, 1417, 1398, 1281, 1347, 1405, 1342, 0, 0, + 229, 1408, 1341, 0, 1371, 0, 1423, 1276, 1362, 0, + 1279, 1283, 1419, 1403, 1312, 275, 0, 0, 0, 0, + 0, 0, 0, 1338, 1349, 1383, 1387, 1332, 0, 0, + 0, 0, 0, 0, 3177, 0, 1310, 0, 1358, 0, + 0, 0, 1288, 1280, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, + 0, 1291, 0, 1311, 1384, 0, 1274, 297, 1285, 400, + 257, 0, 451, 1391, 1402, 1333, 622, 1404, 1331, 1330, + 1378, 1289, 1397, 1324, 363, 1287, 330, 197, 225, 0, + 1322, 410, 459, 471, 1396, 1307, 1316, 253, 1314, 469, + 424, 599, 233, 284, 456, 430, 467, 438, 287, 1357, + 1376, 468, 370, 582, 448, 596, 623, 624, 263, 404, + 609, 519, 617, 641, 226, 260, 418, 504, 602, 492, + 395, 578, 579, 329, 491, 295, 201, 367, 629, 224, + 477, 369, 242, 231, 584, 606, 299, 289, 454, 636, + 213, 514, 594, 239, 481, 0, 0, 644, 247, 502, + 215, 591, 501, 391, 326, 327, 214, 0, 455, 268, + 293, 0, 0, 258, 413, 586, 587, 256, 645, 228, + 616, 220, 1286, 615, 406, 581, 592, 392, 381, 219, + 590, 390, 380, 334, 353, 354, 280, 307, 445, 373, + 446, 306, 308, 402, 401, 403, 207, 603, 0, 208, + 0, 497, 605, 646, 450, 212, 234, 235, 237, 1302, + 279, 283, 291, 294, 303, 304, 313, 365, 417, 444, + 440, 449, 1392, 576, 597, 610, 621, 627, 628, 630, + 631, 632, 633, 634, 637, 635, 405, 311, 493, 333, + 371, 1381, 1422, 423, 470, 240, 601, 494, 199, 1296, + 1301, 1294, 0, 254, 255, 1363, 572, 1297, 1295, 1352, + 1353, 1298, 1413, 1414, 1415, 1400, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, - 661, 662, 640, 503, 509, 504, 505, 506, 507, 508, - 0, 510, 907, 756, 755, 0, 762, 763, 0, 792, - 793, 795, 799, 800, 801, 812, 859, 860, 868, 870, - 871, 869, 872, 873, 874, 877, 878, 879, 880, 875, - 876, 881, 775, 779, 776, 777, 778, 790, 780, 781, - 782, 783, 784, 785, 786, 787, 788, 789, 791, 930, - 931, 932, 933, 934, 935, 805, 809, 808, 806, 807, - 803, 804, 831, 830, 832, 833, 834, 835, 836, 837, - 839, 838, 840, 841, 842, 843, 844, 845, 813, 814, - 817, 818, 816, 815, 819, 828, 829, 820, 821, 822, - 823, 824, 825, 827, 826, 846, 847, 848, 849, 850, - 852, 851, 855, 856, 854, 853, 858, 857, 754, 196, - 220, 365, 0, 451, 287, 641, 610, 481, 605, 205, - 222, 921, 261, 922, 0, 0, 926, 0, 0, 0, - 928, 927, 0, 929, 891, 890, 0, 0, 923, 924, - 0, 925, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 309, 317, 318, 321, - 327, 377, 383, 384, 385, 386, 406, 407, 408, 411, - 414, 415, 418, 420, 421, 424, 428, 432, 433, 434, - 436, 438, 440, 452, 457, 471, 472, 473, 474, 475, - 478, 479, 485, 486, 487, 488, 489, 497, 498, 511, - 581, 583, 598, 617, 623, 477, 936, 937, 938, 939, - 940, 941, 942, 943, 299, 593, 624, 591, 636, 618, - 435, 375, 0, 0, 378, 280, 304, 319, 0, 609, - 499, 226, 463, 289, 250, 961, 0, 210, 245, 229, - 258, 273, 276, 323, 388, 397, 426, 431, 295, 270, - 243, 456, 240, 482, 514, 515, 516, 518, 392, 265, - 430, 393, 0, 373, 571, 572, 315, 0, 523, 0, - 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 413, 0, 0, 0, 0, 753, 0, 0, 0, 269, - 758, 0, 0, 0, 363, 266, 0, 0, 427, 0, - 203, 0, 484, 251, 374, 371, 578, 281, 272, 268, - 249, 316, 382, 425, 513, 419, 765, 367, 0, 0, - 494, 398, 0, 0, 0, 0, 0, 760, 761, 0, - 0, 0, 0, 0, 0, 2402, 0, 322, 247, 324, - 202, 410, 495, 285, 0, 95, 0, 0, 1010, 946, - 737, 912, 950, 1011, 963, 964, 965, 951, 0, 237, - 952, 953, 244, 954, 0, 911, 796, 798, 797, 861, - 862, 863, 864, 865, 866, 867, 794, 959, 602, 966, - 967, 2403, 264, 320, 271, 263, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, - 0, 0, 0, 733, 750, 0, 764, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 747, 748, 0, - 0, 0, 0, 906, 0, 749, 0, 0, 757, 968, - 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, - 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, - 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, - 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, - 1009, 759, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 399, 256, 0, 450, 905, 0, - 0, 620, 0, 0, 903, 0, 0, 0, 0, 362, - 0, 329, 197, 224, 0, 0, 409, 458, 470, 0, - 0, 0, 956, 0, 468, 423, 597, 232, 283, 455, - 429, 466, 437, 286, 0, 0, 467, 369, 580, 447, - 594, 621, 622, 262, 403, 607, 517, 615, 639, 225, - 259, 417, 502, 600, 491, 394, 576, 577, 328, 490, - 294, 201, 366, 627, 223, 476, 368, 241, 230, 582, - 604, 298, 288, 453, 634, 212, 512, 592, 238, 480, - 0, 0, 642, 246, 501, 214, 589, 500, 390, 325, - 326, 213, 0, 454, 267, 292, 0, 0, 257, 412, - 957, 958, 255, 643, 802, 614, 219, 0, 613, 405, - 579, 590, 391, 380, 218, 588, 389, 379, 333, 810, - 811, 279, 306, 887, 886, 885, 305, 307, 883, 884, - 882, 206, 601, 0, 207, 0, 496, 603, 644, 449, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 302, - 303, 312, 364, 416, 443, 439, 448, 0, 574, 595, - 608, 619, 625, 626, 628, 629, 630, 631, 632, 635, - 633, 404, 310, 492, 332, 370, 0, 0, 422, 469, - 239, 599, 493, 893, 915, 904, 770, 771, 894, 895, - 919, 896, 773, 774, 916, 917, 767, 768, 772, 918, - 920, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 659, 660, 661, 662, 640, - 503, 509, 504, 505, 506, 507, 508, 0, 510, 907, - 756, 755, 0, 762, 763, 0, 792, 793, 795, 799, - 800, 801, 812, 859, 860, 868, 870, 871, 869, 872, - 873, 874, 877, 878, 879, 880, 875, 876, 881, 775, - 779, 776, 777, 778, 790, 780, 781, 782, 783, 784, - 785, 786, 787, 788, 789, 791, 930, 931, 932, 933, - 934, 935, 805, 809, 808, 806, 807, 803, 804, 831, - 830, 832, 833, 834, 835, 836, 837, 839, 838, 840, - 841, 842, 843, 844, 845, 813, 814, 817, 818, 816, - 815, 819, 828, 829, 820, 821, 822, 823, 824, 825, - 827, 826, 846, 847, 848, 849, 850, 852, 851, 855, - 856, 854, 853, 858, 857, 754, 196, 220, 365, 0, - 451, 287, 641, 610, 481, 605, 205, 222, 921, 261, - 922, 0, 0, 926, 0, 0, 0, 928, 927, 0, - 929, 891, 890, 0, 0, 923, 924, 0, 925, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 309, 317, 318, 321, 327, 377, 383, - 384, 385, 386, 406, 407, 408, 411, 414, 415, 418, - 420, 421, 424, 428, 432, 433, 434, 436, 438, 440, - 452, 457, 471, 472, 473, 474, 475, 478, 479, 485, - 486, 487, 488, 489, 497, 498, 511, 581, 583, 598, - 617, 623, 477, 936, 937, 938, 939, 940, 941, 942, - 943, 299, 593, 624, 591, 636, 618, 435, 375, 0, - 0, 378, 280, 304, 319, 0, 609, 499, 226, 463, - 289, 250, 961, 0, 210, 245, 229, 258, 273, 276, - 323, 388, 397, 426, 431, 295, 270, 243, 456, 240, - 482, 514, 515, 516, 518, 392, 265, 430, 393, 0, - 373, 571, 572, 315, 86, 523, 0, 766, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 413, 0, 0, - 0, 0, 753, 0, 0, 0, 269, 758, 0, 0, - 0, 363, 266, 0, 0, 427, 0, 203, 0, 484, - 251, 374, 371, 578, 281, 272, 268, 249, 316, 382, - 425, 513, 419, 765, 367, 0, 0, 494, 398, 0, - 0, 0, 0, 0, 760, 761, 0, 0, 0, 0, - 0, 0, 0, 0, 322, 247, 324, 202, 410, 495, - 285, 0, 95, 0, 0, 1010, 946, 737, 912, 950, - 1011, 963, 964, 965, 951, 0, 237, 952, 953, 244, - 954, 0, 911, 796, 798, 797, 861, 862, 863, 864, - 865, 866, 867, 794, 959, 602, 966, 967, 0, 264, - 320, 271, 263, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 733, 750, 0, 764, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 747, 748, 0, 0, 0, 0, - 906, 0, 749, 0, 0, 757, 968, 969, 970, 971, - 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, - 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, - 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, - 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 759, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 399, 256, 0, 450, 905, 0, 0, 620, 0, - 0, 903, 0, 0, 0, 0, 362, 0, 329, 197, - 224, 0, 0, 409, 458, 470, 0, 0, 0, 956, - 0, 468, 423, 597, 232, 283, 455, 429, 466, 437, - 286, 0, 0, 467, 369, 580, 447, 594, 621, 622, - 262, 403, 607, 517, 615, 639, 225, 259, 417, 502, - 600, 491, 394, 576, 577, 328, 490, 294, 201, 366, - 627, 223, 476, 368, 241, 230, 582, 604, 298, 288, - 453, 634, 212, 512, 592, 238, 480, 0, 0, 642, - 246, 501, 214, 589, 500, 390, 325, 326, 213, 0, - 454, 267, 292, 0, 0, 257, 412, 957, 958, 255, - 643, 802, 614, 219, 0, 613, 405, 579, 590, 391, - 380, 218, 588, 389, 379, 333, 810, 811, 279, 306, - 887, 886, 885, 305, 307, 883, 884, 882, 206, 601, - 0, 207, 0, 496, 603, 644, 449, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 302, 303, 312, 364, - 416, 443, 439, 448, 0, 574, 595, 608, 619, 625, - 626, 628, 629, 630, 631, 632, 635, 633, 404, 310, - 492, 332, 370, 0, 0, 422, 469, 239, 599, 493, - 893, 915, 904, 770, 771, 894, 895, 919, 896, 773, - 774, 916, 917, 767, 768, 772, 918, 920, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 659, 660, 661, 662, 640, 503, 509, 504, - 505, 506, 507, 508, 0, 510, 907, 756, 755, 0, - 762, 763, 0, 792, 793, 795, 799, 800, 801, 812, - 859, 860, 868, 870, 871, 869, 872, 873, 874, 877, - 878, 879, 880, 875, 876, 881, 775, 779, 776, 777, - 778, 790, 780, 781, 782, 783, 784, 785, 786, 787, - 788, 789, 791, 930, 931, 932, 933, 934, 935, 805, - 809, 808, 806, 807, 803, 804, 831, 830, 832, 833, - 834, 835, 836, 837, 839, 838, 840, 841, 842, 843, - 844, 845, 813, 814, 817, 818, 816, 815, 819, 828, - 829, 820, 821, 822, 823, 824, 825, 827, 826, 846, - 847, 848, 849, 850, 852, 851, 855, 856, 854, 853, - 858, 857, 754, 196, 220, 365, 94, 451, 287, 641, - 610, 481, 605, 205, 222, 921, 261, 922, 0, 0, - 926, 0, 0, 0, 928, 927, 0, 929, 891, 890, - 0, 0, 923, 924, 0, 925, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 309, 317, 318, 321, 327, 377, 383, 384, 385, 386, - 406, 407, 408, 411, 414, 415, 418, 420, 421, 424, - 428, 432, 433, 434, 436, 438, 440, 452, 457, 471, - 472, 473, 474, 475, 478, 479, 485, 486, 487, 488, - 489, 497, 498, 511, 581, 583, 598, 617, 623, 477, - 936, 937, 938, 939, 940, 941, 942, 943, 299, 593, - 624, 591, 636, 618, 435, 375, 0, 0, 378, 280, - 304, 319, 0, 609, 499, 226, 463, 289, 250, 961, - 0, 210, 245, 229, 258, 273, 276, 323, 388, 397, - 426, 431, 295, 270, 243, 456, 240, 482, 514, 515, - 516, 518, 392, 265, 430, 393, 0, 373, 571, 572, - 315, 0, 523, 0, 766, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 413, 0, 0, 0, 0, 753, - 0, 0, 0, 269, 758, 0, 0, 0, 363, 266, - 0, 0, 427, 0, 203, 0, 484, 251, 374, 371, - 578, 281, 272, 268, 249, 316, 382, 425, 513, 419, - 765, 367, 0, 0, 494, 398, 0, 0, 0, 0, - 0, 760, 761, 0, 0, 0, 0, 0, 0, 0, - 0, 322, 247, 324, 202, 410, 495, 285, 0, 95, - 0, 0, 1010, 946, 737, 912, 950, 1011, 963, 964, - 965, 951, 0, 237, 952, 953, 244, 954, 0, 911, - 796, 798, 797, 861, 862, 863, 864, 865, 866, 867, - 794, 959, 602, 966, 967, 0, 264, 320, 271, 263, - 575, 0, 0, 0, 0, 0, 0, 0, 0, 228, - 0, 0, 0, 0, 0, 0, 0, 733, 750, 0, - 764, 0, 0, 0, 274, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 747, 748, 0, 0, 0, 0, 906, 0, 749, - 0, 0, 757, 968, 969, 970, 971, 972, 973, 974, - 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, - 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, - 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, - 1005, 1006, 1007, 1008, 1009, 759, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 399, 256, - 0, 450, 905, 0, 0, 620, 0, 0, 903, 0, - 0, 0, 0, 362, 0, 329, 197, 224, 0, 0, - 409, 458, 470, 0, 0, 0, 956, 0, 468, 423, - 597, 232, 283, 455, 429, 466, 437, 286, 4045, 0, - 467, 369, 580, 447, 594, 621, 622, 262, 403, 607, - 517, 615, 639, 225, 259, 417, 502, 600, 491, 394, - 576, 577, 328, 490, 294, 201, 366, 627, 223, 476, - 368, 241, 230, 582, 604, 298, 288, 453, 634, 212, - 512, 592, 238, 480, 0, 0, 642, 246, 501, 214, - 589, 500, 390, 325, 326, 213, 0, 454, 267, 292, - 0, 0, 257, 412, 957, 958, 255, 643, 802, 614, - 219, 0, 613, 405, 579, 590, 391, 380, 218, 588, - 389, 379, 333, 810, 811, 279, 306, 887, 886, 885, - 305, 307, 883, 884, 882, 206, 601, 0, 207, 0, - 496, 603, 644, 449, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 302, 303, 312, 364, 416, 443, 439, - 448, 0, 574, 595, 608, 619, 625, 626, 628, 629, - 630, 631, 632, 635, 633, 404, 310, 492, 332, 370, - 0, 0, 422, 469, 239, 599, 493, 893, 915, 904, - 770, 771, 894, 895, 919, 896, 773, 774, 916, 917, - 767, 768, 772, 918, 920, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, - 660, 661, 662, 640, 503, 509, 504, 505, 506, 507, - 508, 0, 510, 907, 756, 755, 0, 762, 763, 0, - 792, 793, 795, 799, 800, 801, 812, 859, 860, 868, - 870, 871, 869, 872, 873, 874, 877, 878, 879, 880, - 875, 876, 881, 775, 779, 776, 777, 778, 790, 780, - 781, 782, 783, 784, 785, 786, 787, 788, 789, 791, - 930, 931, 932, 933, 934, 935, 805, 809, 808, 806, - 807, 803, 804, 831, 830, 832, 833, 834, 835, 836, - 837, 839, 838, 840, 841, 842, 843, 844, 845, 813, - 814, 817, 818, 816, 815, 819, 828, 829, 820, 821, - 822, 823, 824, 825, 827, 826, 846, 847, 848, 849, - 850, 852, 851, 855, 856, 854, 853, 858, 857, 754, - 196, 220, 365, 0, 451, 287, 641, 610, 481, 605, - 205, 222, 921, 261, 922, 0, 0, 926, 0, 0, - 0, 928, 927, 0, 929, 891, 890, 0, 0, 923, - 924, 0, 925, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 309, 317, 318, - 321, 327, 377, 383, 384, 385, 386, 406, 407, 408, - 411, 414, 415, 418, 420, 421, 424, 428, 432, 433, - 434, 436, 438, 440, 452, 457, 471, 472, 473, 474, - 475, 478, 479, 485, 486, 487, 488, 489, 497, 498, - 511, 581, 583, 598, 617, 623, 477, 936, 937, 938, - 939, 940, 941, 942, 943, 299, 593, 624, 591, 636, - 618, 435, 375, 0, 0, 378, 280, 304, 319, 0, - 609, 499, 226, 463, 289, 250, 961, 0, 210, 245, - 229, 258, 273, 276, 323, 388, 397, 426, 431, 295, - 270, 243, 456, 240, 482, 514, 515, 516, 518, 392, - 265, 430, 393, 0, 373, 571, 572, 315, 0, 523, - 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 413, 0, 0, 0, 0, 753, 0, 0, 0, - 269, 758, 0, 0, 0, 363, 266, 0, 0, 427, - 0, 203, 0, 484, 251, 374, 371, 578, 281, 272, - 268, 249, 316, 382, 425, 513, 419, 765, 367, 0, - 0, 494, 398, 0, 0, 0, 0, 0, 760, 761, - 0, 0, 0, 0, 0, 0, 0, 0, 322, 247, - 324, 202, 410, 495, 285, 0, 95, 0, 1727, 1010, - 946, 737, 912, 950, 1011, 963, 964, 965, 951, 0, - 237, 952, 953, 244, 954, 0, 911, 796, 798, 797, - 861, 862, 863, 864, 865, 866, 867, 794, 959, 602, - 966, 967, 0, 264, 320, 271, 263, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, - 0, 0, 0, 0, 733, 750, 0, 764, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 747, 748, - 0, 0, 0, 0, 906, 0, 749, 0, 0, 757, - 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, - 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, - 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, - 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, - 1008, 1009, 759, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 399, 256, 0, 450, 905, - 0, 0, 620, 0, 0, 903, 0, 0, 0, 0, - 362, 0, 329, 197, 224, 0, 0, 409, 458, 470, - 0, 0, 0, 956, 0, 468, 423, 597, 232, 283, - 455, 429, 466, 437, 286, 0, 0, 467, 369, 580, - 447, 594, 621, 622, 262, 403, 607, 517, 615, 639, - 225, 259, 417, 502, 600, 491, 394, 576, 577, 328, - 490, 294, 201, 366, 627, 223, 476, 368, 241, 230, - 582, 604, 298, 288, 453, 634, 212, 512, 592, 238, - 480, 0, 0, 642, 246, 501, 214, 589, 500, 390, - 325, 326, 213, 0, 454, 267, 292, 0, 0, 257, - 412, 957, 958, 255, 643, 802, 614, 219, 0, 613, - 405, 579, 590, 391, 380, 218, 588, 389, 379, 333, - 810, 811, 279, 306, 887, 886, 885, 305, 307, 883, - 884, 882, 206, 601, 0, 207, 0, 496, 603, 644, - 449, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 302, 303, 312, 364, 416, 443, 439, 448, 0, 574, - 595, 608, 619, 625, 626, 628, 629, 630, 631, 632, - 635, 633, 404, 310, 492, 332, 370, 0, 0, 422, - 469, 239, 599, 493, 893, 915, 904, 770, 771, 894, - 895, 919, 896, 773, 774, 916, 917, 767, 768, 772, - 918, 920, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, - 640, 503, 509, 504, 505, 506, 507, 508, 0, 510, - 907, 756, 755, 0, 762, 763, 0, 792, 793, 795, - 799, 800, 801, 812, 859, 860, 868, 870, 871, 869, - 872, 873, 874, 877, 878, 879, 880, 875, 876, 881, - 775, 779, 776, 777, 778, 790, 780, 781, 782, 783, - 784, 785, 786, 787, 788, 789, 791, 930, 931, 932, - 933, 934, 935, 805, 809, 808, 806, 807, 803, 804, - 831, 830, 832, 833, 834, 835, 836, 837, 839, 838, - 840, 841, 842, 843, 844, 845, 813, 814, 817, 818, - 816, 815, 819, 828, 829, 820, 821, 822, 823, 824, - 825, 827, 826, 846, 847, 848, 849, 850, 852, 851, - 855, 856, 854, 853, 858, 857, 754, 196, 220, 365, - 0, 451, 287, 641, 610, 481, 605, 205, 222, 921, - 261, 922, 0, 0, 926, 0, 0, 0, 928, 927, - 0, 929, 891, 890, 0, 0, 923, 924, 0, 925, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 309, 317, 318, 321, 327, 377, - 383, 384, 385, 386, 406, 407, 408, 411, 414, 415, - 418, 420, 421, 424, 428, 432, 433, 434, 436, 438, - 440, 452, 457, 471, 472, 473, 474, 475, 478, 479, - 485, 486, 487, 488, 489, 497, 498, 511, 581, 583, - 598, 617, 623, 477, 936, 937, 938, 939, 940, 941, - 942, 943, 299, 593, 624, 591, 636, 618, 435, 375, - 0, 0, 378, 280, 304, 319, 0, 609, 499, 226, - 463, 289, 250, 961, 0, 210, 245, 229, 258, 273, - 276, 323, 388, 397, 426, 431, 295, 270, 243, 456, - 240, 482, 514, 515, 516, 518, 392, 265, 430, 393, - 0, 373, 571, 572, 315, 0, 523, 0, 766, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 413, 0, - 0, 0, 0, 753, 0, 0, 0, 269, 758, 0, - 0, 0, 363, 266, 0, 0, 427, 0, 203, 0, - 484, 251, 374, 371, 578, 281, 272, 268, 249, 316, - 382, 425, 513, 419, 765, 367, 0, 0, 494, 398, - 0, 0, 0, 0, 0, 760, 761, 0, 0, 0, - 0, 0, 0, 0, 0, 322, 247, 324, 202, 410, - 495, 285, 0, 95, 0, 0, 1010, 946, 737, 912, - 950, 1011, 963, 964, 965, 951, 0, 237, 952, 953, - 244, 954, 0, 911, 796, 798, 797, 861, 862, 863, - 864, 865, 866, 867, 794, 959, 602, 966, 967, 0, - 264, 320, 271, 263, 575, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 733, 750, 0, 764, 0, 0, 0, 274, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 747, 748, 1056, 0, 0, - 0, 906, 0, 749, 0, 0, 757, 968, 969, 970, - 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, - 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, - 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, - 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 759, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 399, 256, 0, 450, 905, 0, 0, 620, - 0, 0, 903, 0, 0, 0, 0, 362, 0, 329, - 197, 224, 0, 0, 409, 458, 470, 0, 0, 0, - 956, 0, 468, 423, 597, 232, 283, 455, 429, 466, - 437, 286, 0, 0, 467, 369, 580, 447, 594, 621, - 622, 262, 403, 607, 517, 615, 639, 225, 259, 417, - 502, 600, 491, 394, 576, 577, 328, 490, 294, 201, - 366, 627, 223, 476, 368, 241, 230, 582, 604, 298, - 288, 453, 634, 212, 512, 592, 238, 480, 0, 0, - 642, 246, 501, 214, 589, 500, 390, 325, 326, 213, - 0, 454, 267, 292, 0, 0, 257, 412, 957, 958, - 255, 643, 802, 614, 219, 0, 613, 405, 579, 590, - 391, 380, 218, 588, 389, 379, 333, 810, 811, 279, - 306, 887, 886, 885, 305, 307, 883, 884, 882, 206, - 601, 0, 207, 0, 496, 603, 644, 449, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 302, 303, 312, - 364, 416, 443, 439, 448, 0, 574, 595, 608, 619, - 625, 626, 628, 629, 630, 631, 632, 635, 633, 404, - 310, 492, 332, 370, 0, 0, 422, 469, 239, 599, - 493, 893, 915, 904, 770, 771, 894, 895, 919, 896, - 773, 774, 916, 917, 767, 768, 772, 918, 920, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 659, 660, 661, 662, 640, 503, 509, - 504, 505, 506, 507, 508, 0, 510, 907, 756, 755, - 0, 762, 763, 0, 792, 793, 795, 799, 800, 801, - 812, 859, 860, 868, 870, 871, 869, 872, 873, 874, - 877, 878, 879, 880, 875, 876, 881, 775, 779, 776, - 777, 778, 790, 780, 781, 782, 783, 784, 785, 786, - 787, 788, 789, 791, 930, 931, 932, 933, 934, 935, - 805, 809, 808, 806, 807, 803, 804, 831, 830, 832, - 833, 834, 835, 836, 837, 839, 838, 840, 841, 842, - 843, 844, 845, 813, 814, 817, 818, 816, 815, 819, - 828, 829, 820, 821, 822, 823, 824, 825, 827, 826, - 846, 847, 848, 849, 850, 852, 851, 855, 856, 854, - 853, 858, 857, 754, 196, 220, 365, 0, 451, 287, - 641, 610, 481, 605, 205, 222, 921, 261, 922, 0, - 0, 926, 0, 0, 0, 928, 927, 0, 929, 891, - 890, 0, 0, 923, 924, 0, 925, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 309, 317, 318, 321, 327, 377, 383, 384, 385, - 386, 406, 407, 408, 411, 414, 415, 418, 420, 421, - 424, 428, 432, 433, 434, 436, 438, 440, 452, 457, - 471, 472, 473, 474, 475, 478, 479, 485, 486, 487, - 488, 489, 497, 498, 511, 581, 583, 598, 617, 623, - 477, 936, 937, 938, 939, 940, 941, 942, 943, 299, - 593, 624, 591, 636, 618, 435, 375, 0, 0, 378, - 280, 304, 319, 0, 609, 499, 226, 463, 289, 250, - 961, 0, 210, 245, 229, 258, 273, 276, 323, 388, - 397, 426, 431, 295, 270, 243, 456, 240, 482, 514, - 515, 516, 518, 392, 265, 430, 393, 0, 373, 571, - 572, 315, 0, 523, 0, 766, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 413, 0, 0, 0, 0, - 753, 0, 0, 0, 269, 758, 0, 0, 0, 363, - 266, 0, 0, 427, 0, 203, 0, 484, 251, 374, - 371, 578, 281, 272, 268, 249, 316, 382, 425, 513, - 419, 765, 367, 0, 0, 494, 398, 0, 0, 0, - 0, 0, 760, 761, 0, 0, 0, 0, 0, 0, - 0, 0, 322, 247, 324, 202, 410, 495, 285, 0, - 95, 0, 0, 1010, 946, 737, 912, 950, 1011, 963, - 964, 965, 951, 0, 237, 952, 953, 244, 954, 0, - 911, 796, 798, 797, 861, 862, 863, 864, 865, 866, - 867, 794, 959, 602, 966, 967, 0, 264, 320, 271, - 263, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 733, 750, - 0, 764, 0, 0, 0, 274, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 747, 748, 0, 0, 0, 0, 906, 0, - 749, 0, 0, 757, 968, 969, 970, 971, 972, 973, - 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, - 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, - 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, - 1004, 1005, 1006, 1007, 1008, 1009, 759, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 399, - 256, 0, 450, 905, 0, 0, 620, 0, 0, 903, - 0, 0, 0, 0, 362, 0, 329, 197, 224, 0, - 0, 409, 458, 470, 0, 0, 0, 956, 0, 468, - 423, 597, 232, 283, 455, 429, 466, 437, 286, 0, - 0, 467, 369, 580, 447, 594, 621, 622, 262, 403, - 607, 517, 615, 639, 225, 259, 417, 502, 600, 491, - 394, 576, 577, 328, 490, 294, 201, 366, 627, 223, - 476, 368, 241, 230, 582, 604, 298, 288, 453, 634, - 212, 512, 592, 238, 480, 0, 0, 642, 246, 501, - 214, 589, 500, 390, 325, 326, 213, 0, 454, 267, - 292, 0, 0, 257, 412, 957, 958, 255, 643, 802, - 614, 219, 0, 613, 405, 579, 590, 391, 380, 218, - 588, 389, 379, 333, 810, 811, 279, 306, 887, 886, - 885, 305, 307, 883, 884, 882, 206, 601, 0, 207, - 0, 496, 603, 644, 449, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 302, 303, 312, 364, 416, 443, - 439, 448, 0, 574, 595, 608, 619, 625, 626, 628, - 629, 630, 631, 632, 635, 633, 404, 310, 492, 332, - 370, 0, 0, 422, 469, 239, 599, 493, 893, 915, - 904, 770, 771, 894, 895, 919, 896, 773, 774, 916, - 917, 767, 768, 772, 918, 920, 645, 646, 647, 648, + 661, 662, 663, 664, 642, 505, 511, 506, 507, 508, + 509, 510, 0, 512, 1385, 1290, 0, 1299, 1300, 396, + 1394, 588, 589, 665, 382, 484, 598, 335, 347, 350, + 340, 359, 0, 360, 336, 337, 342, 344, 345, 346, + 351, 352, 356, 362, 249, 210, 388, 397, 575, 312, + 216, 217, 218, 521, 522, 523, 524, 613, 614, 618, + 205, 460, 461, 462, 463, 292, 608, 309, 466, 465, + 331, 332, 377, 447, 537, 539, 550, 554, 556, 558, + 564, 567, 538, 540, 551, 555, 557, 559, 565, 568, + 527, 529, 531, 533, 546, 545, 542, 570, 571, 548, + 553, 532, 544, 549, 562, 569, 566, 526, 530, 534, + 543, 561, 560, 541, 552, 563, 547, 535, 528, 536, + 1356, 196, 221, 366, 1418, 452, 288, 643, 612, 482, + 607, 206, 223, 1293, 262, 1305, 1313, 0, 1319, 1327, + 1328, 1340, 1343, 1344, 1345, 1346, 1364, 1365, 1367, 1375, + 1377, 1380, 1382, 1389, 1401, 1421, 198, 200, 209, 222, + 232, 236, 243, 261, 276, 278, 285, 298, 310, 318, + 319, 322, 328, 378, 384, 385, 386, 387, 407, 408, + 409, 412, 415, 416, 419, 421, 422, 425, 429, 433, + 434, 435, 437, 439, 441, 453, 458, 472, 473, 474, + 475, 476, 479, 480, 486, 487, 488, 489, 490, 498, + 499, 513, 583, 585, 600, 619, 625, 478, 301, 302, + 442, 443, 314, 315, 639, 640, 300, 595, 626, 593, + 638, 620, 436, 376, 1355, 1361, 379, 281, 305, 320, + 1370, 611, 500, 227, 464, 290, 251, 1388, 1390, 211, + 246, 230, 259, 274, 277, 324, 389, 398, 427, 432, + 296, 271, 244, 457, 241, 483, 516, 517, 518, 520, + 393, 266, 431, 1351, 1379, 374, 573, 574, 316, 394, + 0, 0, 0, 0, 0, 1407, 1393, 525, 0, 1335, + 1410, 1304, 1323, 1420, 1326, 1329, 1372, 1282, 1350, 414, + 1320, 1308, 1277, 1315, 1278, 1306, 1337, 270, 1303, 1395, + 1354, 1409, 364, 267, 1284, 1275, 204, 503, 1309, 428, + 1325, 203, 1374, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 1416, 368, 1360, + 0, 495, 399, 0, 0, 0, 1339, 1399, 1348, 1386, + 1334, 1373, 1292, 1359, 1411, 1321, 1369, 1412, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 948, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 1317, 1366, 604, + 1406, 1318, 1368, 265, 321, 272, 264, 577, 1417, 1398, + 1281, 1347, 1405, 1342, 0, 0, 229, 1408, 1341, 0, + 1371, 0, 1423, 1276, 1362, 0, 1279, 1283, 1419, 1403, + 1312, 275, 0, 0, 0, 0, 0, 0, 0, 1338, + 1349, 1383, 1387, 1332, 0, 0, 0, 0, 0, 0, + 2379, 0, 1310, 0, 1358, 0, 0, 0, 1288, 1280, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1336, 0, 0, 0, 0, 1291, 0, 1311, + 1384, 0, 1274, 297, 1285, 400, 257, 0, 451, 1391, + 1402, 1333, 622, 1404, 1331, 1330, 1378, 1289, 1397, 1324, + 363, 1287, 330, 197, 225, 0, 1322, 410, 459, 471, + 1396, 1307, 1316, 253, 1314, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 1357, 1376, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 1286, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 1302, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 1392, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 1381, 1422, 423, + 470, 240, 601, 494, 199, 1296, 1301, 1294, 0, 254, + 255, 1363, 572, 1297, 1295, 1352, 1353, 1298, 1413, 1414, + 1415, 1400, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 1385, 1290, 0, 1299, 1300, 396, 1394, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 1356, 196, 221, 366, + 1418, 452, 288, 643, 612, 482, 607, 206, 223, 1293, + 262, 1305, 1313, 0, 1319, 1327, 1328, 1340, 1343, 1344, + 1345, 1346, 1364, 1365, 1367, 1375, 1377, 1380, 1382, 1389, + 1401, 1421, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 1355, 1361, 379, 281, 305, 320, 1370, 611, 500, 227, + 464, 290, 251, 1388, 1390, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 1351, + 1379, 374, 573, 574, 316, 394, 0, 0, 0, 0, + 0, 1407, 1393, 525, 0, 1335, 1410, 1304, 1323, 1420, + 1326, 1329, 1372, 1282, 1350, 414, 1320, 1308, 1277, 1315, + 1278, 1306, 1337, 270, 1303, 1395, 1354, 1409, 364, 267, + 1284, 1275, 204, 503, 1309, 428, 1325, 203, 1374, 485, + 252, 375, 372, 580, 282, 273, 269, 250, 317, 383, + 426, 515, 420, 1416, 368, 1360, 0, 495, 399, 0, + 0, 0, 1339, 1399, 1348, 1386, 1334, 1373, 1292, 1359, + 1411, 1321, 1369, 1412, 323, 248, 325, 202, 411, 496, + 286, 0, 95, 0, 0, 0, 715, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 238, 0, 0, 245, + 0, 0, 0, 349, 358, 357, 338, 339, 341, 343, + 348, 355, 361, 1317, 1366, 604, 1406, 1318, 1368, 265, + 321, 272, 264, 577, 1417, 1398, 1281, 1347, 1405, 1342, + 0, 0, 229, 1408, 1341, 0, 1371, 0, 1423, 1276, + 1362, 0, 1279, 1283, 1419, 1403, 1312, 275, 0, 0, + 0, 0, 0, 0, 0, 1338, 1349, 1383, 1387, 1332, + 0, 0, 0, 0, 0, 0, 0, 0, 1310, 0, + 1358, 0, 0, 0, 1288, 1280, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, + 0, 0, 0, 1291, 0, 1311, 1384, 0, 1274, 297, + 1285, 400, 257, 0, 451, 1391, 1402, 1333, 622, 1404, + 1331, 1330, 1378, 1289, 1397, 1324, 363, 1287, 330, 197, + 225, 0, 1322, 410, 459, 471, 1396, 1307, 1316, 253, + 1314, 469, 424, 599, 233, 284, 456, 430, 467, 438, + 287, 1357, 1376, 468, 370, 582, 448, 596, 623, 624, + 263, 404, 609, 519, 617, 641, 226, 260, 418, 504, + 602, 492, 395, 578, 579, 329, 491, 295, 201, 367, + 629, 224, 477, 369, 242, 231, 584, 606, 299, 289, + 454, 636, 213, 514, 594, 239, 481, 0, 0, 644, + 247, 502, 215, 591, 501, 391, 326, 327, 214, 0, + 455, 268, 293, 0, 0, 258, 413, 586, 587, 256, + 645, 228, 616, 220, 1286, 615, 406, 581, 592, 392, + 381, 219, 590, 390, 380, 334, 353, 354, 280, 307, + 445, 373, 446, 306, 308, 402, 401, 403, 207, 603, + 0, 208, 0, 497, 605, 646, 450, 212, 234, 235, + 237, 1302, 279, 283, 291, 294, 303, 304, 313, 365, + 417, 444, 440, 449, 1392, 576, 597, 610, 621, 627, + 628, 630, 631, 632, 633, 634, 637, 635, 405, 311, + 493, 333, 371, 1381, 1422, 423, 470, 240, 601, 494, + 199, 1296, 1301, 1294, 0, 254, 255, 1363, 572, 1297, + 1295, 1352, 1353, 1298, 1413, 1414, 1415, 1400, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 659, 660, 661, 662, 640, 503, 509, 504, 505, 506, - 507, 508, 0, 510, 907, 756, 755, 0, 762, 763, - 0, 792, 793, 795, 799, 800, 801, 812, 859, 860, - 868, 870, 871, 869, 872, 873, 874, 877, 878, 879, - 880, 875, 876, 881, 775, 779, 776, 777, 778, 790, - 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, - 791, 930, 931, 932, 933, 934, 935, 805, 809, 808, - 806, 807, 803, 804, 831, 830, 832, 833, 834, 835, - 836, 837, 839, 838, 840, 841, 842, 843, 844, 845, - 813, 814, 817, 818, 816, 815, 819, 828, 829, 820, - 821, 822, 823, 824, 825, 827, 826, 846, 847, 848, - 849, 850, 852, 851, 855, 856, 854, 853, 858, 857, - 754, 196, 220, 365, 0, 451, 287, 641, 610, 481, - 605, 205, 222, 921, 261, 922, 0, 0, 926, 0, - 0, 0, 928, 927, 0, 929, 891, 890, 0, 0, - 923, 924, 0, 925, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 309, 317, - 318, 321, 327, 377, 383, 384, 385, 386, 406, 407, - 408, 411, 414, 415, 418, 420, 421, 424, 428, 432, - 433, 434, 436, 438, 440, 452, 457, 471, 472, 473, - 474, 475, 478, 479, 485, 486, 487, 488, 489, 497, - 498, 511, 581, 583, 598, 617, 623, 477, 936, 937, - 938, 939, 940, 941, 942, 943, 299, 593, 624, 591, - 636, 618, 435, 375, 0, 0, 378, 280, 304, 319, - 0, 609, 499, 226, 463, 289, 250, 961, 0, 210, - 245, 229, 258, 273, 276, 323, 388, 397, 426, 431, - 295, 270, 243, 456, 240, 482, 514, 515, 516, 518, - 392, 265, 430, 393, 0, 373, 571, 572, 315, 0, - 523, 0, 766, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 413, 0, 0, 0, 0, 753, 0, 0, - 0, 269, 758, 0, 0, 0, 363, 266, 0, 0, - 427, 0, 203, 0, 484, 251, 374, 371, 578, 281, - 272, 268, 249, 316, 382, 425, 513, 419, 765, 367, - 0, 0, 494, 398, 0, 0, 0, 0, 0, 760, - 761, 0, 0, 0, 0, 0, 0, 0, 0, 322, - 247, 324, 202, 410, 495, 285, 0, 95, 0, 0, - 1010, 946, 737, 912, 950, 1011, 963, 964, 965, 951, - 0, 237, 952, 953, 244, 954, 0, 911, 796, 798, - 797, 861, 862, 863, 864, 865, 866, 867, 794, 959, - 602, 966, 967, 0, 264, 320, 271, 263, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, - 0, 0, 0, 0, 0, 733, 750, 0, 764, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 747, - 748, 0, 0, 0, 0, 906, 0, 749, 0, 0, - 757, 968, 969, 970, 971, 972, 973, 974, 975, 976, - 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, - 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, - 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, - 1007, 1008, 1009, 3124, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 399, 256, 0, 450, - 905, 0, 0, 620, 0, 0, 903, 0, 0, 0, - 0, 362, 0, 329, 197, 224, 0, 0, 409, 458, - 470, 0, 0, 0, 956, 0, 468, 423, 597, 232, - 283, 455, 429, 466, 437, 286, 0, 0, 467, 369, - 580, 447, 594, 621, 622, 262, 403, 607, 517, 615, - 639, 225, 259, 417, 502, 600, 491, 394, 576, 577, - 328, 490, 294, 201, 366, 627, 223, 476, 368, 241, - 230, 582, 604, 298, 288, 453, 634, 212, 512, 592, - 238, 480, 0, 0, 642, 246, 501, 214, 589, 500, - 390, 325, 326, 213, 0, 454, 267, 292, 0, 0, - 257, 412, 957, 958, 255, 643, 802, 614, 219, 0, - 613, 405, 579, 590, 391, 380, 218, 588, 389, 379, - 333, 810, 811, 279, 306, 887, 886, 885, 305, 307, - 883, 884, 882, 206, 601, 0, 207, 0, 496, 603, - 644, 449, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 302, 303, 312, 364, 416, 443, 439, 448, 0, - 574, 595, 608, 619, 625, 626, 628, 629, 630, 631, - 632, 635, 633, 404, 310, 492, 332, 370, 0, 0, - 422, 469, 239, 599, 493, 893, 915, 904, 770, 771, - 894, 895, 919, 896, 773, 774, 916, 917, 767, 768, - 772, 918, 920, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, - 662, 640, 503, 509, 504, 505, 506, 507, 508, 0, - 510, 907, 756, 755, 0, 762, 763, 0, 792, 793, - 795, 799, 800, 801, 812, 859, 860, 868, 870, 871, - 869, 872, 873, 874, 877, 878, 879, 880, 875, 876, - 881, 775, 779, 776, 777, 778, 790, 780, 781, 782, - 783, 784, 785, 786, 787, 788, 789, 791, 930, 931, - 932, 933, 934, 935, 805, 809, 808, 806, 807, 803, - 804, 831, 830, 832, 833, 834, 835, 836, 837, 839, - 838, 840, 841, 842, 843, 844, 845, 813, 814, 817, - 818, 816, 815, 819, 828, 829, 820, 821, 822, 823, - 824, 825, 827, 826, 846, 847, 848, 849, 850, 852, - 851, 855, 856, 854, 853, 858, 857, 754, 196, 220, - 365, 0, 451, 287, 641, 610, 481, 605, 205, 222, - 921, 261, 922, 0, 0, 926, 0, 0, 0, 928, - 927, 0, 929, 891, 890, 0, 0, 923, 924, 0, - 925, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 309, 317, 318, 321, 327, - 377, 383, 384, 385, 386, 406, 407, 408, 411, 414, - 415, 418, 420, 421, 424, 428, 432, 433, 434, 436, - 438, 440, 452, 457, 471, 472, 473, 474, 475, 478, - 479, 485, 486, 487, 488, 489, 497, 498, 511, 581, - 583, 598, 617, 623, 477, 936, 937, 938, 939, 940, - 941, 942, 943, 299, 593, 624, 591, 636, 618, 435, - 375, 0, 0, 378, 280, 304, 319, 0, 609, 499, - 226, 463, 289, 250, 961, 0, 210, 245, 229, 258, - 273, 276, 323, 388, 397, 426, 431, 295, 270, 243, - 456, 240, 482, 514, 515, 516, 518, 392, 265, 430, - 393, 0, 373, 571, 572, 315, 0, 523, 0, 766, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 413, - 0, 0, 0, 0, 753, 0, 0, 0, 269, 758, - 0, 0, 0, 363, 266, 0, 0, 427, 0, 203, - 0, 484, 251, 374, 371, 578, 281, 272, 268, 249, - 316, 382, 425, 513, 419, 765, 367, 0, 0, 494, - 398, 0, 0, 0, 0, 0, 760, 761, 0, 0, - 0, 0, 0, 0, 0, 0, 322, 247, 324, 202, - 410, 495, 285, 0, 95, 0, 0, 1010, 946, 737, - 912, 950, 1011, 963, 964, 965, 951, 0, 237, 952, - 953, 244, 954, 0, 911, 796, 798, 797, 861, 862, - 863, 864, 865, 866, 867, 794, 959, 602, 966, 967, - 0, 264, 320, 271, 263, 575, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 733, 750, 0, 764, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 747, 748, 0, 0, - 0, 0, 906, 0, 749, 0, 0, 757, 968, 969, + 659, 660, 661, 662, 663, 664, 642, 505, 511, 506, + 507, 508, 509, 510, 0, 512, 1385, 1290, 0, 1299, + 1300, 396, 1394, 588, 589, 665, 382, 484, 598, 335, + 347, 350, 340, 359, 0, 360, 336, 337, 342, 344, + 345, 346, 351, 352, 356, 362, 249, 210, 388, 397, + 575, 312, 216, 217, 218, 521, 522, 523, 524, 613, + 614, 618, 205, 460, 461, 462, 463, 292, 608, 309, + 466, 465, 331, 332, 377, 447, 537, 539, 550, 554, + 556, 558, 564, 567, 538, 540, 551, 555, 557, 559, + 565, 568, 527, 529, 531, 533, 546, 545, 542, 570, + 571, 548, 553, 532, 544, 549, 562, 569, 566, 526, + 530, 534, 543, 561, 560, 541, 552, 563, 547, 535, + 528, 536, 1356, 196, 221, 366, 1418, 452, 288, 643, + 612, 482, 607, 206, 223, 1293, 262, 1305, 1313, 0, + 1319, 1327, 1328, 1340, 1343, 1344, 1345, 1346, 1364, 1365, + 1367, 1375, 1377, 1380, 1382, 1389, 1401, 1421, 198, 200, + 209, 222, 232, 236, 243, 261, 276, 278, 285, 298, + 310, 318, 319, 322, 328, 378, 384, 385, 386, 387, + 407, 408, 409, 412, 415, 416, 419, 421, 422, 425, + 429, 433, 434, 435, 437, 439, 441, 453, 458, 472, + 473, 474, 475, 476, 479, 480, 486, 487, 488, 489, + 490, 498, 499, 513, 583, 585, 600, 619, 625, 478, + 301, 302, 442, 443, 314, 315, 639, 640, 300, 595, + 626, 593, 638, 620, 436, 376, 1355, 1361, 379, 281, + 305, 320, 1370, 611, 500, 227, 464, 290, 251, 1388, + 1390, 211, 246, 230, 259, 274, 277, 324, 389, 398, + 427, 432, 296, 271, 244, 457, 241, 483, 516, 517, + 518, 520, 393, 266, 431, 1351, 1379, 374, 573, 574, + 316, 394, 0, 0, 0, 0, 0, 1407, 1393, 525, + 0, 1335, 1410, 1304, 1323, 1420, 1326, 1329, 1372, 1282, + 1350, 414, 1320, 1308, 1277, 1315, 1278, 1306, 1337, 270, + 1303, 1395, 1354, 1409, 364, 267, 1284, 1275, 204, 503, + 1309, 428, 1325, 203, 1374, 485, 252, 375, 372, 580, + 282, 273, 269, 250, 317, 383, 426, 515, 420, 1416, + 368, 1360, 0, 495, 399, 0, 0, 0, 1339, 1399, + 1348, 1386, 1334, 1373, 1292, 1359, 1411, 1321, 1369, 1412, + 323, 248, 325, 202, 411, 496, 286, 0, 0, 0, + 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 238, 0, 0, 245, 0, 0, 0, 349, + 358, 357, 338, 339, 341, 343, 348, 355, 361, 1317, + 1366, 604, 1406, 1318, 1368, 265, 321, 272, 264, 577, + 1417, 1398, 1281, 1347, 1405, 1342, 0, 0, 229, 1408, + 1341, 0, 1371, 0, 1423, 1276, 1362, 0, 1279, 1283, + 1419, 1403, 1312, 275, 0, 0, 0, 0, 0, 0, + 0, 1338, 1349, 1383, 1387, 1332, 0, 0, 0, 0, + 0, 0, 0, 0, 1310, 0, 1358, 0, 0, 0, + 1288, 1280, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1336, 0, 0, 0, 0, 1291, + 0, 1311, 1384, 0, 1274, 297, 1285, 400, 257, 0, + 451, 1391, 1402, 1333, 622, 1404, 1331, 1330, 1378, 1289, + 1397, 1324, 363, 1287, 330, 197, 225, 0, 1322, 410, + 459, 471, 1396, 1307, 1316, 253, 1314, 469, 424, 599, + 233, 284, 456, 430, 467, 438, 287, 1357, 1376, 468, + 370, 582, 448, 596, 623, 624, 263, 404, 609, 519, + 617, 641, 226, 260, 418, 504, 602, 492, 395, 578, + 579, 329, 491, 295, 201, 367, 629, 224, 477, 369, + 242, 231, 584, 606, 299, 289, 454, 636, 213, 514, + 594, 239, 481, 0, 0, 644, 247, 502, 215, 591, + 501, 391, 326, 327, 214, 0, 455, 268, 293, 0, + 0, 258, 413, 586, 587, 256, 645, 228, 616, 220, + 1286, 615, 406, 581, 592, 392, 381, 219, 590, 390, + 380, 334, 353, 354, 280, 307, 445, 373, 446, 306, + 308, 402, 401, 403, 207, 603, 0, 208, 0, 497, + 605, 646, 450, 212, 234, 235, 237, 1302, 279, 283, + 291, 294, 303, 304, 313, 365, 417, 444, 440, 449, + 1392, 576, 597, 610, 621, 627, 628, 630, 631, 632, + 633, 634, 637, 635, 405, 311, 493, 333, 371, 1381, + 1422, 423, 470, 240, 601, 494, 199, 1296, 1301, 1294, + 0, 254, 255, 1363, 572, 1297, 1295, 1352, 1353, 1298, + 1413, 1414, 1415, 1400, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, + 663, 664, 642, 505, 511, 506, 507, 508, 509, 510, + 0, 512, 1385, 1290, 0, 1299, 1300, 396, 1394, 588, + 589, 665, 382, 484, 598, 335, 347, 350, 340, 359, + 0, 360, 336, 337, 342, 344, 345, 346, 351, 352, + 356, 362, 249, 210, 388, 397, 575, 312, 216, 217, + 218, 521, 522, 523, 524, 613, 614, 618, 205, 460, + 461, 462, 463, 292, 608, 309, 466, 465, 331, 332, + 377, 447, 537, 539, 550, 554, 556, 558, 564, 567, + 538, 540, 551, 555, 557, 559, 565, 568, 527, 529, + 531, 533, 546, 545, 542, 570, 571, 548, 553, 532, + 544, 549, 562, 569, 566, 526, 530, 534, 543, 561, + 560, 541, 552, 563, 547, 535, 528, 536, 1356, 196, + 221, 366, 1418, 452, 288, 643, 612, 482, 607, 206, + 223, 1293, 262, 1305, 1313, 0, 1319, 1327, 1328, 1340, + 1343, 1344, 1345, 1346, 1364, 1365, 1367, 1375, 1377, 1380, + 1382, 1389, 1401, 1421, 198, 200, 209, 222, 232, 236, + 243, 261, 276, 278, 285, 298, 310, 318, 319, 322, + 328, 378, 384, 385, 386, 387, 407, 408, 409, 412, + 415, 416, 419, 421, 422, 425, 429, 433, 434, 435, + 437, 439, 441, 453, 458, 472, 473, 474, 475, 476, + 479, 480, 486, 487, 488, 489, 490, 498, 499, 513, + 583, 585, 600, 619, 625, 478, 301, 302, 442, 443, + 314, 315, 639, 640, 300, 595, 626, 593, 638, 620, + 436, 376, 1355, 1361, 379, 281, 305, 320, 1370, 611, + 500, 227, 464, 290, 251, 1388, 1390, 211, 246, 230, + 259, 274, 277, 324, 389, 398, 427, 432, 296, 271, + 244, 457, 241, 483, 516, 517, 518, 520, 393, 266, + 431, 1351, 1379, 374, 573, 574, 316, 394, 0, 0, + 0, 0, 0, 1407, 1393, 525, 0, 1335, 1410, 1304, + 1323, 1420, 1326, 1329, 1372, 1282, 1350, 414, 1320, 1308, + 1277, 1315, 1278, 1306, 1337, 270, 1303, 1395, 1354, 1409, + 364, 267, 1284, 1275, 204, 503, 1309, 428, 1325, 203, + 1374, 485, 252, 375, 372, 580, 282, 273, 269, 250, + 317, 383, 426, 515, 420, 1416, 368, 1360, 0, 495, + 399, 0, 0, 0, 1339, 1399, 1348, 1386, 1334, 1373, + 1292, 1359, 1411, 1321, 1369, 1412, 323, 248, 325, 202, + 411, 496, 286, 0, 0, 0, 0, 0, 715, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, + 0, 245, 0, 0, 0, 349, 358, 357, 338, 339, + 341, 343, 348, 355, 361, 1317, 1366, 604, 1406, 1318, + 1368, 265, 321, 272, 264, 577, 1417, 1398, 1281, 1347, + 1405, 1342, 0, 0, 229, 1408, 1341, 0, 1371, 0, + 1423, 1276, 1362, 0, 1279, 1283, 1419, 1403, 1312, 275, + 0, 0, 0, 0, 0, 0, 0, 1338, 1349, 1383, + 1387, 1332, 0, 0, 0, 0, 0, 0, 0, 0, + 1310, 0, 1358, 0, 0, 0, 1288, 1280, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1336, 0, 0, 0, 0, 1291, 0, 1311, 1384, 0, + 1274, 297, 1285, 400, 257, 0, 451, 1391, 1402, 1333, + 622, 1404, 1331, 1330, 1378, 1289, 1397, 1324, 363, 1287, + 330, 197, 225, 0, 1322, 410, 459, 471, 1396, 1307, + 1316, 253, 1314, 469, 424, 599, 233, 284, 456, 430, + 467, 438, 287, 1357, 1376, 468, 370, 582, 448, 596, + 623, 624, 263, 404, 609, 519, 617, 641, 226, 260, + 418, 504, 602, 492, 395, 578, 579, 329, 491, 295, + 201, 367, 629, 224, 477, 369, 242, 231, 584, 606, + 299, 289, 454, 636, 213, 514, 594, 239, 481, 0, + 0, 644, 247, 502, 215, 591, 501, 391, 326, 327, + 214, 0, 455, 268, 293, 0, 0, 258, 413, 586, + 587, 256, 645, 228, 616, 220, 1286, 615, 406, 581, + 592, 392, 381, 219, 590, 390, 380, 334, 353, 354, + 280, 307, 445, 373, 446, 306, 308, 402, 401, 403, + 207, 603, 0, 208, 0, 497, 605, 646, 450, 212, + 234, 235, 237, 1302, 279, 283, 291, 294, 303, 304, + 313, 365, 417, 444, 440, 449, 1392, 576, 597, 610, + 621, 627, 628, 630, 631, 632, 633, 634, 637, 635, + 405, 311, 493, 333, 371, 1381, 1422, 423, 470, 240, + 601, 494, 199, 1296, 1301, 1294, 0, 254, 255, 1363, + 572, 1297, 1295, 1352, 1353, 1298, 1413, 1414, 1415, 1400, + 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, + 657, 658, 659, 660, 661, 662, 663, 664, 642, 505, + 511, 506, 507, 508, 509, 510, 0, 512, 1385, 1290, + 0, 1299, 1300, 396, 1394, 588, 589, 665, 382, 484, + 598, 335, 347, 350, 340, 359, 0, 360, 336, 337, + 342, 344, 345, 346, 351, 352, 356, 362, 249, 210, + 388, 397, 575, 312, 216, 217, 218, 521, 522, 523, + 524, 613, 614, 618, 205, 460, 461, 462, 463, 292, + 608, 309, 466, 465, 331, 332, 377, 447, 537, 539, + 550, 554, 556, 558, 564, 567, 538, 540, 551, 555, + 557, 559, 565, 568, 527, 529, 531, 533, 546, 545, + 542, 570, 571, 548, 553, 532, 544, 549, 562, 569, + 566, 526, 530, 534, 543, 561, 560, 541, 552, 563, + 547, 535, 528, 536, 1356, 196, 221, 366, 1418, 452, + 288, 643, 612, 482, 607, 206, 223, 1293, 262, 1305, + 1313, 0, 1319, 1327, 1328, 1340, 1343, 1344, 1345, 1346, + 1364, 1365, 1367, 1375, 1377, 1380, 1382, 1389, 1401, 1421, + 198, 200, 209, 222, 232, 236, 243, 261, 276, 278, + 285, 298, 310, 318, 319, 322, 328, 378, 384, 385, + 386, 387, 407, 408, 409, 412, 415, 416, 419, 421, + 422, 425, 429, 433, 434, 435, 437, 439, 441, 453, + 458, 472, 473, 474, 475, 476, 479, 480, 486, 487, + 488, 489, 490, 498, 499, 513, 583, 585, 600, 619, + 625, 478, 301, 302, 442, 443, 314, 315, 639, 640, + 300, 595, 626, 593, 638, 620, 436, 376, 1355, 1361, + 379, 281, 305, 320, 1370, 611, 500, 227, 464, 290, + 251, 1388, 1390, 211, 246, 230, 259, 274, 277, 324, + 389, 398, 427, 432, 296, 271, 244, 457, 241, 483, + 516, 517, 518, 520, 393, 266, 431, 1351, 1379, 374, + 573, 574, 316, 394, 0, 0, 0, 0, 0, 1407, + 1393, 525, 0, 1335, 1410, 1304, 1323, 1420, 1326, 1329, + 1372, 1282, 1350, 414, 1320, 1308, 1277, 1315, 1278, 1306, + 1337, 270, 1303, 1395, 1354, 1409, 364, 267, 1284, 1275, + 204, 503, 1309, 428, 1325, 203, 1374, 485, 252, 375, + 372, 580, 282, 273, 269, 250, 317, 383, 426, 515, + 420, 1416, 368, 1360, 0, 495, 399, 0, 0, 0, + 1339, 1399, 1348, 1386, 1334, 1373, 1292, 1359, 1411, 1321, + 1369, 1412, 323, 248, 325, 202, 411, 496, 286, 0, + 0, 0, 0, 0, 948, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 238, 0, 0, 245, 0, 0, + 0, 349, 358, 357, 338, 339, 341, 343, 348, 355, + 361, 1317, 1366, 604, 1406, 1318, 1368, 265, 321, 272, + 264, 577, 1417, 1398, 1281, 1347, 1405, 1342, 0, 0, + 229, 1408, 1341, 0, 1371, 0, 1423, 1276, 1362, 0, + 1279, 1283, 1419, 1403, 1312, 275, 0, 0, 0, 0, + 0, 0, 0, 1338, 1349, 1383, 1387, 1332, 0, 0, + 0, 0, 0, 0, 0, 0, 1310, 0, 1358, 0, + 0, 0, 1288, 1280, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, + 0, 1291, 0, 1311, 1384, 0, 1274, 297, 1285, 400, + 257, 0, 451, 1391, 1402, 1333, 622, 1404, 1331, 1330, + 1378, 1289, 1397, 1324, 363, 1287, 330, 197, 225, 0, + 1322, 410, 459, 471, 1396, 1307, 1316, 253, 1314, 469, + 424, 599, 233, 284, 456, 430, 467, 438, 287, 1357, + 1376, 468, 370, 582, 448, 596, 623, 624, 263, 404, + 609, 519, 617, 641, 226, 260, 418, 504, 602, 492, + 395, 578, 579, 329, 491, 295, 201, 367, 629, 224, + 477, 369, 242, 231, 584, 606, 299, 289, 454, 636, + 213, 514, 594, 239, 481, 0, 0, 644, 247, 502, + 215, 591, 501, 391, 326, 327, 214, 0, 455, 268, + 293, 0, 0, 258, 413, 586, 587, 256, 645, 228, + 616, 220, 1286, 615, 406, 581, 592, 392, 381, 219, + 590, 390, 380, 334, 353, 354, 280, 307, 445, 373, + 446, 306, 308, 402, 401, 403, 207, 603, 0, 208, + 0, 497, 605, 646, 450, 212, 234, 235, 237, 1302, + 279, 283, 291, 294, 303, 304, 313, 365, 417, 444, + 440, 449, 1392, 576, 597, 610, 621, 627, 628, 630, + 631, 632, 633, 634, 637, 635, 405, 311, 493, 333, + 371, 1381, 1422, 423, 470, 240, 601, 494, 199, 1296, + 1301, 1294, 0, 254, 255, 1363, 572, 1297, 1295, 1352, + 1353, 1298, 1413, 1414, 1415, 1400, 647, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, + 661, 662, 663, 664, 642, 505, 511, 506, 507, 508, + 509, 510, 0, 512, 1385, 1290, 0, 1299, 1300, 396, + 1394, 588, 589, 665, 382, 484, 598, 335, 347, 350, + 340, 359, 0, 360, 336, 337, 342, 344, 345, 346, + 351, 352, 356, 362, 249, 210, 388, 397, 575, 312, + 216, 217, 218, 521, 522, 523, 524, 613, 614, 618, + 205, 460, 461, 462, 463, 292, 608, 309, 466, 465, + 331, 332, 377, 447, 537, 539, 550, 554, 556, 558, + 564, 567, 538, 540, 551, 555, 557, 559, 565, 568, + 527, 529, 531, 533, 546, 545, 542, 570, 571, 548, + 553, 532, 544, 549, 562, 569, 566, 526, 530, 534, + 543, 561, 560, 541, 552, 563, 547, 535, 528, 536, + 1356, 196, 221, 366, 1418, 452, 288, 643, 612, 482, + 607, 206, 223, 1293, 262, 1305, 1313, 0, 1319, 1327, + 1328, 1340, 1343, 1344, 1345, 1346, 1364, 1365, 1367, 1375, + 1377, 1380, 1382, 1389, 1401, 1421, 198, 200, 209, 222, + 232, 236, 243, 261, 276, 278, 285, 298, 310, 318, + 319, 322, 328, 378, 384, 385, 386, 387, 407, 408, + 409, 412, 415, 416, 419, 421, 422, 425, 429, 433, + 434, 435, 437, 439, 441, 453, 458, 472, 473, 474, + 475, 476, 479, 480, 486, 487, 488, 489, 490, 498, + 499, 513, 583, 585, 600, 619, 625, 478, 301, 302, + 442, 443, 314, 315, 639, 640, 300, 595, 626, 593, + 638, 620, 436, 376, 1355, 1361, 379, 281, 305, 320, + 1370, 611, 500, 227, 464, 290, 251, 1388, 1390, 211, + 246, 230, 259, 274, 277, 324, 389, 398, 427, 432, + 296, 271, 244, 457, 241, 483, 516, 517, 518, 520, + 393, 266, 431, 1351, 1379, 374, 573, 574, 316, 394, + 0, 0, 0, 0, 0, 0, 0, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 1012, + 948, 739, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 0, 265, 321, 272, 264, 577, 0, 0, + 2201, 2202, 2203, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 735, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 0, 0, 0, 0, 908, 0, 751, 0, 0, 759, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, - 3120, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 399, 256, 0, 450, 905, 0, 0, - 620, 0, 0, 903, 0, 0, 0, 0, 362, 0, - 329, 197, 224, 0, 0, 409, 458, 470, 0, 0, - 0, 956, 0, 468, 423, 597, 232, 283, 455, 429, - 466, 437, 286, 0, 0, 467, 369, 580, 447, 594, - 621, 622, 262, 403, 607, 517, 615, 639, 225, 259, - 417, 502, 600, 491, 394, 576, 577, 328, 490, 294, - 201, 366, 627, 223, 476, 368, 241, 230, 582, 604, - 298, 288, 453, 634, 212, 512, 592, 238, 480, 0, - 0, 642, 246, 501, 214, 589, 500, 390, 325, 326, - 213, 0, 454, 267, 292, 0, 0, 257, 412, 957, - 958, 255, 643, 802, 614, 219, 0, 613, 405, 579, - 590, 391, 380, 218, 588, 389, 379, 333, 810, 811, - 279, 306, 887, 886, 885, 305, 307, 883, 884, 882, - 206, 601, 0, 207, 0, 496, 603, 644, 449, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 302, 303, - 312, 364, 416, 443, 439, 448, 0, 574, 595, 608, - 619, 625, 626, 628, 629, 630, 631, 632, 635, 633, - 404, 310, 492, 332, 370, 0, 0, 422, 469, 239, - 599, 493, 893, 915, 904, 770, 771, 894, 895, 919, - 896, 773, 774, 916, 917, 767, 768, 772, 918, 920, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 659, 660, 661, 662, 640, 503, - 509, 504, 505, 506, 507, 508, 0, 510, 907, 756, - 755, 0, 762, 763, 0, 792, 793, 795, 799, 800, - 801, 812, 859, 860, 868, 870, 871, 869, 872, 873, - 874, 877, 878, 879, 880, 875, 876, 881, 775, 779, - 776, 777, 778, 790, 780, 781, 782, 783, 784, 785, - 786, 787, 788, 789, 791, 930, 931, 932, 933, 934, - 935, 805, 809, 808, 806, 807, 803, 804, 831, 830, - 832, 833, 834, 835, 836, 837, 839, 838, 840, 841, - 842, 843, 844, 845, 813, 814, 817, 818, 816, 815, - 819, 828, 829, 820, 821, 822, 823, 824, 825, 827, - 826, 846, 847, 848, 849, 850, 852, 851, 855, 856, - 854, 853, 858, 857, 754, 196, 220, 365, 0, 451, - 287, 641, 610, 481, 605, 205, 222, 921, 261, 922, - 0, 0, 926, 0, 0, 0, 928, 927, 0, 929, - 891, 890, 0, 0, 923, 924, 0, 925, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 309, 317, 318, 321, 327, 377, 383, 384, - 385, 386, 406, 407, 408, 411, 414, 415, 418, 420, - 421, 424, 428, 432, 433, 434, 436, 438, 440, 452, - 457, 471, 472, 473, 474, 475, 478, 479, 485, 486, - 487, 488, 489, 497, 498, 511, 581, 583, 598, 617, - 623, 477, 936, 937, 938, 939, 940, 941, 942, 943, - 299, 593, 624, 591, 636, 618, 435, 375, 0, 0, - 378, 280, 304, 319, 0, 609, 499, 226, 463, 289, - 250, 961, 0, 210, 245, 229, 258, 273, 276, 323, - 388, 397, 426, 431, 295, 270, 243, 456, 240, 482, - 514, 515, 516, 518, 392, 265, 430, 393, 0, 373, - 571, 572, 315, 0, 523, 0, 766, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 413, 0, 0, 0, - 0, 753, 0, 0, 0, 269, 758, 0, 0, 0, - 363, 266, 0, 0, 427, 0, 203, 0, 484, 251, - 374, 371, 578, 281, 272, 268, 249, 316, 382, 425, - 513, 419, 765, 367, 0, 0, 494, 398, 0, 0, - 0, 0, 0, 760, 761, 0, 0, 0, 0, 0, - 0, 0, 0, 322, 247, 324, 202, 410, 495, 285, - 0, 95, 0, 0, 1010, 946, 1077, 912, 950, 1011, - 963, 964, 965, 951, 0, 237, 952, 953, 244, 954, - 0, 911, 796, 798, 797, 861, 862, 863, 864, 865, - 866, 867, 794, 959, 602, 966, 967, 0, 264, 320, - 271, 263, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 750, 0, 764, 0, 0, 0, 274, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 747, 748, 0, 0, 0, 0, 906, - 0, 749, 0, 0, 757, 968, 969, 970, 971, 972, - 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, - 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, - 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, - 1003, 1004, 1005, 1006, 1007, 1008, 1009, 759, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 399, 256, 0, 450, 905, 0, 0, 620, 0, 0, - 903, 0, 0, 0, 0, 362, 0, 329, 197, 224, - 0, 0, 409, 458, 470, 0, 0, 0, 956, 0, - 468, 423, 597, 232, 283, 455, 429, 466, 437, 286, - 0, 0, 467, 369, 580, 447, 594, 621, 622, 262, - 403, 607, 517, 615, 639, 225, 259, 417, 502, 600, - 491, 394, 576, 577, 328, 490, 294, 201, 366, 627, - 223, 476, 368, 241, 230, 582, 604, 298, 288, 453, - 634, 212, 512, 592, 238, 480, 0, 0, 642, 246, - 501, 214, 589, 500, 390, 325, 326, 213, 0, 454, - 267, 292, 0, 0, 257, 412, 957, 958, 255, 643, - 802, 614, 219, 0, 613, 405, 579, 590, 391, 380, - 218, 588, 389, 379, 333, 810, 811, 279, 306, 887, - 886, 885, 305, 307, 883, 884, 882, 206, 601, 0, - 207, 0, 496, 603, 644, 449, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 302, 303, 312, 364, 416, - 443, 439, 448, 0, 574, 595, 608, 619, 625, 626, - 628, 629, 630, 631, 632, 635, 633, 404, 310, 492, - 332, 370, 0, 0, 422, 469, 239, 599, 493, 893, - 915, 904, 770, 771, 894, 895, 919, 896, 773, 774, - 916, 917, 767, 768, 772, 918, 920, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 659, 660, 661, 662, 640, 503, 509, 504, 505, - 506, 507, 508, 0, 510, 907, 756, 755, 0, 762, - 763, 0, 792, 793, 795, 799, 800, 801, 812, 859, - 860, 868, 870, 871, 869, 872, 873, 874, 877, 878, - 879, 880, 875, 876, 881, 775, 779, 776, 777, 778, - 790, 780, 781, 782, 783, 784, 785, 786, 787, 788, - 789, 791, 930, 931, 932, 933, 934, 935, 805, 809, - 808, 806, 807, 803, 804, 831, 830, 832, 833, 834, - 835, 836, 837, 839, 838, 840, 841, 842, 843, 844, - 845, 813, 814, 817, 818, 816, 815, 819, 828, 829, - 820, 821, 822, 823, 824, 825, 827, 826, 846, 847, - 848, 849, 850, 852, 851, 855, 856, 854, 853, 858, - 857, 754, 196, 220, 365, 0, 451, 287, 641, 610, - 481, 605, 205, 222, 921, 261, 922, 0, 0, 926, - 0, 0, 0, 928, 927, 0, 929, 891, 890, 0, - 0, 923, 924, 0, 925, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 309, - 317, 318, 321, 327, 377, 383, 384, 385, 386, 406, - 407, 408, 411, 414, 415, 418, 420, 421, 424, 428, - 432, 433, 434, 436, 438, 440, 452, 457, 471, 472, - 473, 474, 475, 478, 479, 485, 486, 487, 488, 489, - 497, 498, 511, 581, 583, 598, 617, 623, 477, 936, - 937, 938, 939, 940, 941, 942, 943, 299, 593, 624, - 591, 636, 618, 435, 375, 0, 0, 378, 280, 304, - 319, 0, 609, 499, 226, 463, 289, 250, 961, 0, - 210, 245, 229, 258, 273, 276, 323, 388, 397, 426, - 431, 295, 270, 243, 456, 240, 482, 514, 515, 516, - 518, 392, 265, 430, 393, 0, 373, 571, 572, 315, - 0, 523, 0, 766, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 413, 0, 0, 0, 0, 753, 0, - 0, 0, 269, 758, 0, 0, 0, 363, 266, 0, - 0, 427, 0, 203, 0, 484, 251, 374, 371, 578, - 281, 272, 268, 249, 316, 382, 425, 513, 419, 765, - 367, 0, 0, 494, 398, 0, 0, 0, 0, 0, - 760, 761, 0, 0, 0, 0, 0, 0, 0, 0, - 322, 247, 324, 202, 410, 495, 285, 0, 95, 0, - 0, 1010, 946, 1077, 912, 950, 1011, 963, 964, 965, - 951, 0, 237, 952, 953, 244, 954, 0, 911, 796, - 798, 797, 861, 862, 863, 864, 865, 866, 867, 794, - 959, 602, 966, 967, 0, 264, 320, 271, 263, 575, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 750, 0, 764, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 747, 748, 0, 0, 0, 0, 906, 0, 749, 0, - 0, 757, 968, 969, 970, 971, 972, 973, 974, 975, - 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, - 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, - 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, - 1006, 1007, 1008, 1009, 2088, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 399, 256, 0, - 450, 905, 0, 0, 620, 0, 0, 903, 0, 0, - 0, 0, 362, 0, 329, 197, 224, 0, 0, 409, - 458, 470, 0, 0, 0, 956, 0, 468, 423, 597, - 232, 283, 455, 429, 466, 437, 286, 0, 0, 467, - 369, 580, 447, 594, 621, 622, 262, 403, 607, 517, - 615, 639, 225, 259, 417, 502, 600, 491, 394, 576, - 577, 328, 490, 294, 201, 366, 627, 223, 476, 368, - 241, 230, 582, 604, 298, 288, 453, 634, 212, 512, - 592, 238, 480, 0, 0, 642, 246, 501, 214, 589, - 500, 390, 325, 326, 213, 0, 454, 267, 292, 0, - 0, 257, 412, 957, 958, 255, 643, 802, 614, 219, - 0, 613, 405, 579, 590, 391, 380, 218, 588, 389, - 379, 333, 810, 811, 279, 306, 887, 886, 885, 305, - 307, 883, 884, 882, 206, 601, 0, 207, 0, 496, - 603, 644, 449, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 302, 303, 312, 364, 416, 443, 439, 448, - 0, 574, 595, 608, 619, 625, 626, 628, 629, 630, - 631, 632, 635, 633, 404, 310, 492, 332, 370, 0, - 0, 422, 469, 239, 599, 493, 893, 915, 904, 770, - 771, 894, 895, 919, 896, 773, 774, 916, 917, 767, - 768, 772, 918, 920, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, - 661, 662, 640, 503, 509, 504, 505, 506, 507, 508, - 0, 510, 907, 756, 755, 0, 762, 763, 0, 792, - 793, 795, 799, 800, 801, 812, 859, 860, 868, 870, - 871, 869, 872, 873, 874, 877, 878, 879, 880, 875, - 876, 881, 775, 779, 776, 777, 778, 790, 780, 781, - 782, 783, 784, 785, 786, 787, 788, 789, 791, 930, - 931, 932, 933, 934, 935, 805, 809, 808, 806, 807, - 803, 804, 831, 830, 832, 833, 834, 835, 836, 837, - 839, 838, 840, 841, 842, 843, 844, 845, 813, 814, - 817, 818, 816, 815, 819, 828, 829, 820, 821, 822, - 823, 824, 825, 827, 826, 846, 847, 848, 849, 850, - 852, 851, 855, 856, 854, 853, 858, 857, 754, 196, - 220, 365, 0, 451, 287, 641, 610, 481, 605, 205, - 222, 921, 261, 922, 0, 0, 926, 0, 0, 0, - 928, 927, 0, 929, 891, 890, 0, 0, 923, 924, - 0, 925, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 309, 317, 318, 321, - 327, 377, 383, 384, 385, 386, 406, 407, 408, 411, - 414, 415, 418, 420, 421, 424, 428, 432, 433, 434, - 436, 438, 440, 452, 457, 471, 472, 473, 474, 475, - 478, 479, 485, 486, 487, 488, 489, 497, 498, 511, - 581, 583, 598, 617, 623, 477, 936, 937, 938, 939, - 940, 941, 942, 943, 299, 593, 624, 591, 636, 618, - 435, 375, 0, 0, 378, 280, 304, 319, 0, 609, - 499, 226, 463, 289, 250, 961, 0, 210, 245, 229, - 258, 273, 276, 323, 388, 397, 426, 431, 295, 270, - 243, 456, 240, 482, 514, 515, 516, 518, 392, 265, - 430, 393, 0, 373, 571, 572, 315, 0, 523, 0, - 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 413, 0, 0, 0, 0, 753, 0, 0, 0, 269, - 758, 0, 0, 0, 363, 266, 0, 0, 427, 0, - 203, 0, 484, 251, 374, 371, 578, 281, 272, 268, - 249, 316, 382, 425, 513, 419, 765, 367, 0, 0, - 494, 398, 0, 0, 0, 0, 0, 760, 761, 0, - 0, 0, 0, 0, 0, 0, 0, 322, 247, 324, - 202, 410, 495, 285, 0, 95, 0, 0, 1010, 946, - 1077, 912, 950, 1011, 963, 964, 965, 951, 0, 237, - 952, 953, 244, 954, 0, 911, 796, 798, 797, 861, - 862, 863, 864, 865, 866, 867, 794, 959, 602, 966, - 967, 0, 264, 320, 271, 263, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, - 0, 0, 0, 0, 750, 0, 764, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 747, 748, 0, - 0, 0, 0, 906, 0, 749, 0, 0, 757, 968, - 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, - 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, - 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, - 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, - 1009, 2086, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 399, 256, 0, 450, 905, 0, - 0, 620, 0, 0, 903, 0, 0, 0, 0, 362, - 0, 329, 197, 224, 0, 0, 409, 458, 470, 0, - 0, 0, 956, 0, 468, 423, 597, 232, 283, 455, - 429, 466, 437, 286, 0, 0, 467, 369, 580, 447, - 594, 621, 622, 262, 403, 607, 517, 615, 639, 225, - 259, 417, 502, 600, 491, 394, 576, 577, 328, 490, - 294, 201, 366, 627, 223, 476, 368, 241, 230, 582, - 604, 298, 288, 453, 634, 212, 512, 592, 238, 480, - 0, 0, 642, 246, 501, 214, 589, 500, 390, 325, - 326, 213, 0, 454, 267, 292, 0, 0, 257, 412, - 957, 958, 255, 643, 802, 614, 219, 0, 613, 405, - 579, 590, 391, 380, 218, 588, 389, 379, 333, 810, - 811, 279, 306, 887, 886, 885, 305, 307, 883, 884, - 882, 206, 601, 0, 207, 0, 496, 603, 644, 449, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 302, - 303, 312, 364, 416, 443, 439, 448, 0, 574, 595, - 608, 619, 625, 626, 628, 629, 630, 631, 632, 635, - 633, 404, 310, 492, 332, 370, 0, 0, 422, 469, - 239, 599, 493, 893, 915, 904, 770, 771, 894, 895, - 919, 896, 773, 774, 916, 917, 767, 768, 772, 918, - 920, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 659, 660, 661, 662, 640, - 503, 509, 504, 505, 506, 507, 508, 0, 510, 907, - 756, 755, 0, 762, 763, 0, 792, 793, 795, 799, - 800, 801, 812, 859, 860, 868, 870, 871, 869, 872, - 873, 874, 877, 878, 879, 880, 875, 876, 881, 775, - 779, 776, 777, 778, 790, 780, 781, 782, 783, 784, - 785, 786, 787, 788, 789, 791, 930, 931, 932, 933, - 934, 935, 805, 809, 808, 806, 807, 803, 804, 831, - 830, 832, 833, 834, 835, 836, 837, 839, 838, 840, - 841, 842, 843, 844, 845, 813, 814, 817, 818, 816, - 815, 819, 828, 829, 820, 821, 822, 823, 824, 825, - 827, 826, 846, 847, 848, 849, 850, 852, 851, 855, - 856, 854, 853, 858, 857, 754, 196, 220, 365, 0, - 451, 287, 641, 610, 481, 605, 205, 222, 921, 261, - 922, 0, 0, 926, 0, 0, 0, 928, 927, 0, - 929, 891, 890, 0, 0, 923, 924, 0, 925, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 309, 317, 318, 321, 327, 377, 383, - 384, 385, 386, 406, 407, 408, 411, 414, 415, 418, - 420, 421, 424, 428, 432, 433, 434, 436, 438, 440, - 452, 457, 471, 472, 473, 474, 475, 478, 479, 485, - 486, 487, 488, 489, 497, 498, 511, 581, 583, 598, - 617, 623, 477, 936, 937, 938, 939, 940, 941, 942, - 943, 299, 593, 624, 591, 636, 618, 435, 375, 0, - 0, 378, 280, 304, 319, 0, 609, 499, 226, 463, - 289, 250, 961, 0, 210, 245, 229, 258, 273, 276, - 323, 388, 397, 426, 431, 295, 270, 243, 456, 240, - 482, 514, 515, 516, 518, 392, 265, 430, 393, 0, - 373, 571, 572, 315, 0, 523, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 413, 0, 0, - 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 363, 266, 0, 0, 427, 0, 203, 0, 484, - 251, 374, 371, 578, 281, 272, 268, 249, 316, 382, - 425, 513, 419, 0, 367, 0, 0, 494, 398, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 322, 247, 324, 202, 410, 495, - 285, 0, 0, 0, 0, 0, 713, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 348, 357, 356, 337, 338, 340, 342, - 347, 354, 360, 0, 0, 602, 0, 0, 0, 264, - 320, 271, 263, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 1128, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 399, 256, 0, 450, 0, 0, 1127, 620, 0, - 0, 0, 0, 0, 1124, 1125, 362, 1085, 329, 197, - 224, 1118, 1122, 409, 458, 470, 0, 0, 0, 252, - 0, 468, 423, 597, 232, 283, 455, 429, 466, 437, - 286, 0, 0, 467, 369, 580, 447, 594, 621, 622, - 262, 403, 607, 517, 615, 639, 225, 259, 417, 502, - 600, 491, 394, 576, 577, 328, 490, 294, 201, 366, - 627, 223, 476, 368, 241, 230, 582, 604, 298, 288, - 453, 634, 212, 512, 592, 238, 480, 0, 0, 642, - 246, 501, 214, 589, 500, 390, 325, 326, 213, 0, - 454, 267, 292, 0, 0, 257, 412, 584, 585, 255, - 643, 227, 614, 219, 0, 613, 405, 579, 590, 391, - 380, 218, 588, 389, 379, 333, 352, 353, 279, 306, - 444, 372, 445, 305, 307, 401, 400, 402, 206, 601, - 0, 207, 0, 496, 603, 644, 449, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 302, 303, 312, 364, - 416, 443, 439, 448, 0, 574, 595, 608, 619, 625, - 626, 628, 629, 630, 631, 632, 635, 633, 404, 310, - 492, 332, 370, 0, 0, 422, 469, 239, 599, 493, - 199, 0, 0, 0, 0, 253, 254, 0, 570, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 659, 660, 661, 662, 640, 503, 509, 504, - 505, 506, 507, 508, 0, 510, 0, 0, 0, 0, - 0, 395, 0, 586, 587, 663, 381, 483, 596, 334, - 346, 349, 339, 358, 0, 359, 335, 336, 341, 343, - 344, 345, 350, 351, 355, 361, 248, 209, 387, 396, - 573, 311, 215, 216, 217, 519, 520, 521, 522, 611, - 612, 616, 204, 459, 460, 461, 462, 291, 606, 308, - 465, 464, 330, 331, 376, 446, 535, 537, 548, 552, - 554, 556, 562, 565, 536, 538, 549, 553, 555, 557, - 563, 566, 525, 527, 529, 531, 544, 543, 540, 568, - 569, 546, 551, 530, 542, 547, 560, 567, 564, 524, - 528, 532, 541, 559, 558, 539, 550, 561, 545, 533, - 526, 534, 0, 196, 220, 365, 0, 451, 287, 641, - 610, 481, 605, 205, 222, 0, 261, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 309, 317, 318, 321, 327, 377, 383, 384, 385, 386, - 406, 407, 408, 411, 414, 415, 418, 420, 421, 424, - 428, 432, 433, 434, 436, 438, 440, 452, 457, 471, - 472, 473, 474, 475, 478, 479, 485, 486, 487, 488, - 489, 497, 498, 511, 581, 583, 598, 617, 623, 477, - 300, 301, 441, 442, 313, 314, 637, 638, 299, 593, - 624, 591, 636, 618, 435, 375, 0, 0, 378, 280, - 304, 319, 0, 609, 499, 226, 463, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 323, 388, 397, - 426, 431, 295, 270, 243, 456, 240, 482, 514, 515, - 516, 518, 392, 265, 430, 393, 0, 373, 571, 572, - 315, 0, 523, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 413, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 363, 266, - 0, 0, 427, 0, 203, 0, 484, 251, 374, 371, - 578, 281, 272, 268, 249, 316, 382, 425, 513, 419, - 0, 367, 0, 0, 494, 398, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 322, 247, 324, 202, 410, 495, 285, 0, 0, - 0, 0, 1688, 946, 0, 0, 1685, 0, 0, 0, - 0, 1683, 0, 237, 1684, 1682, 244, 1687, 0, 911, - 348, 357, 356, 337, 338, 340, 342, 347, 354, 360, - 0, 0, 602, 0, 0, 0, 264, 320, 271, 263, - 575, 0, 0, 0, 0, 0, 0, 0, 0, 228, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 399, 256, - 0, 450, 0, 0, 0, 620, 0, 0, 0, 0, - 0, 0, 0, 362, 0, 329, 197, 224, 0, 0, - 409, 458, 470, 0, 0, 0, 252, 0, 468, 423, - 597, 232, 283, 455, 429, 466, 437, 286, 0, 0, - 467, 369, 580, 447, 594, 621, 622, 262, 403, 607, - 517, 615, 639, 225, 259, 417, 502, 600, 491, 394, - 576, 577, 328, 490, 294, 201, 366, 627, 223, 476, - 368, 241, 230, 582, 604, 298, 288, 453, 634, 212, - 512, 592, 238, 480, 0, 0, 642, 246, 501, 214, - 589, 500, 390, 325, 326, 213, 0, 454, 267, 292, - 0, 0, 257, 412, 584, 585, 255, 643, 227, 614, - 219, 0, 613, 405, 579, 590, 391, 380, 218, 588, - 389, 379, 333, 352, 353, 279, 306, 444, 372, 445, - 305, 307, 401, 400, 402, 206, 601, 0, 207, 0, - 496, 603, 644, 449, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 302, 303, 312, 364, 416, 443, 439, - 448, 0, 574, 595, 608, 619, 625, 626, 628, 629, - 630, 631, 632, 635, 633, 404, 310, 492, 332, 370, - 0, 0, 422, 469, 239, 599, 493, 199, 0, 0, - 0, 0, 253, 254, 0, 570, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, - 660, 661, 662, 640, 503, 509, 504, 505, 506, 507, - 508, 0, 510, 0, 0, 0, 0, 0, 395, 0, - 586, 587, 663, 381, 483, 596, 334, 346, 349, 339, - 358, 0, 359, 335, 336, 341, 343, 344, 345, 350, - 351, 355, 361, 248, 209, 387, 396, 573, 311, 215, - 216, 217, 519, 520, 521, 522, 611, 612, 616, 204, - 459, 460, 461, 462, 291, 606, 308, 465, 464, 330, - 331, 376, 446, 535, 537, 548, 552, 554, 556, 562, - 565, 536, 538, 549, 553, 555, 557, 563, 566, 525, - 527, 529, 531, 544, 543, 540, 568, 569, 546, 551, - 530, 542, 547, 560, 567, 564, 524, 528, 532, 541, - 559, 558, 539, 550, 561, 545, 533, 526, 534, 0, - 196, 220, 365, 0, 451, 287, 641, 610, 481, 605, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 309, 317, 318, - 321, 327, 377, 383, 384, 385, 386, 406, 407, 408, - 411, 414, 415, 418, 420, 421, 424, 428, 432, 433, - 434, 436, 438, 440, 452, 457, 471, 472, 473, 474, - 475, 478, 479, 485, 486, 487, 488, 489, 497, 498, - 511, 581, 583, 598, 617, 623, 477, 300, 301, 441, - 442, 313, 314, 637, 638, 299, 593, 624, 591, 636, - 618, 435, 375, 0, 0, 378, 280, 304, 319, 0, - 609, 499, 226, 463, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 323, 388, 397, 426, 431, 295, - 270, 243, 456, 240, 482, 514, 515, 516, 518, 392, - 265, 430, 393, 0, 373, 571, 572, 315, 86, 523, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 413, 0, 0, 0, 0, 0, 0, 0, 0, - 269, 0, 0, 0, 0, 363, 266, 0, 0, 427, - 0, 203, 0, 484, 251, 374, 371, 578, 281, 272, - 268, 249, 316, 382, 425, 513, 419, 0, 367, 0, - 0, 494, 398, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 322, 247, - 324, 202, 410, 495, 285, 0, 95, 0, 0, 0, + 1010, 1011, 761, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 2408, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 1012, + 948, 739, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 2409, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 735, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 0, 0, 0, 0, 908, 0, 751, 0, 0, 759, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, + 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 761, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 86, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 1012, + 948, 739, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 735, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 0, 0, 0, 0, 908, 0, 751, 0, 0, 759, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, + 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 761, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 94, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 1012, + 948, 739, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 735, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 0, 0, 0, 0, 908, 0, 751, 0, 0, 759, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, + 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 761, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 4054, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 1730, 1012, + 948, 739, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 735, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 0, 0, 0, 0, 908, 0, 751, 0, 0, 759, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, + 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 761, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 1012, + 948, 739, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 735, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 1058, 0, 0, 0, 908, 0, 751, 0, 0, 759, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, + 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 761, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 1012, + 948, 739, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 735, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 0, 0, 0, 0, 908, 0, 751, 0, 0, 759, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, + 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 761, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 1012, + 948, 739, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 735, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 0, 0, 0, 0, 908, 0, 751, 0, 0, 759, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, + 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 3133, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 1012, + 948, 739, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 735, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 0, 0, 0, 0, 908, 0, 751, 0, 0, 759, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, + 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 3129, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 1012, + 948, 1079, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 0, 0, 0, 0, 908, 0, 751, 0, 0, 759, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, + 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 761, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 1012, + 948, 1079, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 0, 0, 0, 0, 908, 0, 751, 0, 0, 759, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, + 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 2094, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 768, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 755, 0, 0, 0, 270, 760, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 767, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 762, 763, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 1012, + 948, 1079, 914, 952, 1013, 965, 966, 967, 953, 0, + 238, 954, 955, 245, 956, 0, 913, 798, 800, 799, + 863, 864, 865, 866, 867, 868, 869, 796, 961, 604, + 968, 969, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 752, 0, 766, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 749, 750, + 0, 0, 0, 0, 908, 0, 751, 0, 0, 759, + 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, + 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, + 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, + 1010, 1011, 2092, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 907, + 0, 0, 622, 0, 0, 905, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 958, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 959, 960, 256, 645, 804, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 812, 813, 280, 307, 889, 888, 887, 306, 308, 885, + 886, 884, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 895, 917, 906, 772, 773, 896, + 897, 921, 898, 775, 776, 918, 919, 769, 770, 774, + 920, 922, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 909, 758, 757, 0, 764, 765, 0, 794, 795, 797, + 801, 802, 803, 814, 861, 862, 870, 872, 873, 871, + 874, 875, 876, 879, 880, 881, 882, 877, 878, 883, + 777, 781, 778, 779, 780, 792, 782, 783, 784, 785, + 786, 787, 788, 789, 790, 791, 793, 932, 933, 934, + 935, 936, 937, 807, 811, 810, 808, 809, 805, 806, + 833, 832, 834, 835, 836, 837, 838, 839, 841, 840, + 842, 843, 844, 845, 846, 847, 815, 816, 819, 820, + 818, 817, 821, 830, 831, 822, 823, 824, 825, 826, + 827, 829, 828, 848, 849, 850, 851, 852, 854, 853, + 857, 858, 856, 855, 860, 859, 756, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 923, + 262, 924, 0, 0, 928, 0, 0, 0, 930, 929, + 0, 931, 893, 892, 0, 0, 925, 926, 0, 927, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 938, 939, 940, 941, 942, 943, + 944, 945, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 963, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 1130, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 1129, 622, 0, 0, 0, 0, 0, 1126, 1127, + 363, 1087, 330, 197, 225, 1120, 1124, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 1691, + 948, 0, 0, 1688, 0, 0, 0, 0, 1686, 0, + 238, 1687, 1685, 245, 1690, 0, 913, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 86, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 348, 357, 356, - 337, 338, 340, 342, 347, 354, 360, 0, 0, 602, - 0, 0, 0, 264, 320, 271, 263, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 399, 256, 0, 450, 0, - 0, 0, 620, 0, 0, 0, 0, 0, 0, 0, - 362, 0, 329, 197, 224, 0, 0, 409, 458, 470, - 0, 0, 0, 252, 0, 468, 423, 597, 232, 283, - 455, 429, 466, 437, 286, 0, 0, 467, 369, 580, - 447, 594, 621, 622, 262, 403, 607, 517, 615, 639, - 225, 259, 417, 502, 600, 491, 394, 576, 577, 328, - 490, 294, 201, 366, 627, 223, 476, 368, 241, 230, - 582, 604, 298, 288, 453, 634, 212, 512, 592, 238, - 480, 0, 0, 642, 246, 501, 214, 589, 500, 390, - 325, 326, 213, 0, 454, 267, 292, 0, 0, 257, - 412, 584, 585, 255, 643, 227, 614, 219, 0, 613, - 405, 579, 590, 391, 380, 218, 588, 389, 379, 333, - 352, 353, 279, 306, 444, 372, 445, 305, 307, 401, - 400, 402, 206, 601, 0, 207, 0, 496, 603, 644, - 449, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 302, 303, 312, 364, 416, 443, 439, 448, 0, 574, - 595, 608, 619, 625, 626, 628, 629, 630, 631, 632, - 635, 633, 404, 310, 492, 332, 370, 0, 0, 422, - 469, 239, 599, 493, 199, 0, 0, 0, 0, 253, - 254, 0, 570, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, - 640, 503, 509, 504, 505, 506, 507, 508, 0, 510, - 0, 0, 0, 0, 0, 395, 0, 586, 587, 663, - 381, 483, 596, 334, 346, 349, 339, 358, 0, 359, - 335, 336, 341, 343, 344, 345, 350, 351, 355, 361, - 248, 209, 387, 396, 573, 311, 215, 216, 217, 519, - 520, 521, 522, 611, 612, 616, 204, 459, 460, 461, - 462, 291, 606, 308, 465, 464, 330, 331, 376, 446, - 535, 537, 548, 552, 554, 556, 562, 565, 536, 538, - 549, 553, 555, 557, 563, 566, 525, 527, 529, 531, - 544, 543, 540, 568, 569, 546, 551, 530, 542, 547, - 560, 567, 564, 524, 528, 532, 541, 559, 558, 539, - 550, 561, 545, 533, 526, 534, 0, 196, 220, 365, - 94, 451, 287, 641, 610, 481, 605, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 2389, 0, 0, - 2388, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 309, 317, 318, 321, 327, 377, - 383, 384, 385, 386, 406, 407, 408, 411, 414, 415, - 418, 420, 421, 424, 428, 432, 433, 434, 436, 438, - 440, 452, 457, 471, 472, 473, 474, 475, 478, 479, - 485, 486, 487, 488, 489, 497, 498, 511, 581, 583, - 598, 617, 623, 477, 300, 301, 441, 442, 313, 314, - 637, 638, 299, 593, 624, 591, 636, 618, 435, 375, - 0, 0, 378, 280, 304, 319, 0, 609, 499, 226, - 463, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 323, 388, 397, 426, 431, 295, 270, 243, 456, - 240, 482, 514, 515, 516, 518, 392, 265, 430, 1750, - 0, 373, 571, 572, 315, 0, 523, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 413, 0, - 0, 0, 1752, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 363, 266, 0, 0, 427, 0, 203, 0, - 484, 251, 374, 371, 578, 281, 272, 268, 249, 316, - 382, 425, 513, 419, 0, 367, 0, 0, 494, 398, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 322, 247, 324, 202, 410, - 495, 285, 0, 0, 0, 0, 1754, 713, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 348, 357, 356, 337, 338, 340, - 342, 347, 354, 360, 0, 0, 602, 0, 0, 0, - 264, 320, 271, 263, 575, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 1459, 0, 1460, - 1461, 0, 0, 0, 0, 0, 0, 0, 274, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 399, 256, 0, 450, 0, 0, 0, 620, - 0, 0, 0, 0, 0, 0, 0, 362, 0, 329, - 197, 224, 0, 0, 409, 458, 470, 0, 0, 0, - 252, 0, 468, 423, 597, 232, 283, 455, 429, 466, - 437, 286, 0, 0, 467, 369, 580, 447, 594, 621, - 622, 262, 403, 607, 517, 615, 639, 225, 259, 417, - 502, 600, 491, 394, 576, 577, 328, 490, 294, 201, - 366, 627, 223, 476, 368, 241, 230, 582, 604, 298, - 288, 453, 634, 212, 512, 592, 238, 480, 0, 0, - 642, 246, 501, 214, 589, 500, 390, 325, 326, 213, - 0, 454, 267, 292, 0, 0, 257, 412, 584, 585, - 255, 643, 227, 614, 219, 0, 613, 405, 579, 590, - 391, 380, 218, 588, 389, 379, 333, 352, 353, 279, - 306, 444, 372, 445, 305, 307, 401, 400, 402, 206, - 601, 0, 207, 0, 496, 603, 644, 449, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 302, 303, 312, - 364, 416, 443, 439, 448, 0, 574, 595, 608, 619, - 625, 626, 628, 629, 630, 631, 632, 635, 633, 404, - 310, 492, 332, 370, 0, 0, 422, 469, 239, 599, - 493, 199, 0, 0, 0, 0, 253, 254, 0, 570, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 659, 660, 661, 662, 640, 503, 509, - 504, 505, 506, 507, 508, 0, 510, 0, 0, 0, - 0, 0, 395, 0, 586, 587, 663, 381, 483, 596, - 334, 346, 349, 339, 358, 0, 359, 335, 336, 341, - 343, 344, 345, 350, 351, 355, 361, 248, 209, 387, - 396, 573, 311, 215, 216, 217, 519, 520, 521, 522, - 611, 612, 616, 204, 459, 460, 461, 462, 291, 606, - 308, 465, 464, 330, 331, 376, 446, 535, 537, 548, - 552, 554, 556, 562, 565, 536, 538, 549, 553, 555, - 557, 563, 566, 525, 527, 529, 531, 544, 543, 540, - 568, 569, 546, 551, 530, 542, 547, 560, 567, 564, - 524, 528, 532, 541, 559, 558, 539, 550, 561, 545, - 533, 526, 534, 0, 196, 220, 365, 0, 451, 287, - 641, 610, 481, 605, 205, 222, 0, 261, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 309, 317, 318, 321, 327, 377, 383, 384, 385, - 386, 406, 407, 408, 411, 414, 415, 418, 420, 421, - 424, 428, 432, 433, 434, 436, 438, 440, 452, 457, - 471, 472, 473, 474, 475, 478, 479, 485, 486, 487, - 488, 489, 497, 498, 511, 581, 583, 598, 617, 623, - 477, 300, 301, 441, 442, 313, 314, 637, 638, 299, - 593, 624, 591, 636, 618, 435, 375, 0, 0, 378, - 280, 304, 319, 0, 609, 499, 226, 463, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 323, 388, - 397, 426, 431, 295, 270, 243, 456, 240, 482, 514, - 515, 516, 518, 392, 265, 430, 393, 0, 373, 571, - 572, 315, 86, 523, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 413, 0, 0, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 363, - 266, 0, 0, 427, 0, 203, 0, 484, 251, 374, - 371, 578, 281, 272, 268, 249, 316, 382, 425, 513, - 419, 0, 367, 0, 0, 494, 398, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 322, 247, 324, 202, 410, 495, 285, 0, - 95, 0, 1727, 0, 713, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 348, 357, 356, 337, 338, 340, 342, 347, 354, - 360, 0, 0, 602, 0, 0, 0, 264, 320, 271, - 263, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 399, - 256, 0, 450, 0, 0, 0, 620, 0, 0, 0, - 0, 0, 0, 0, 362, 0, 329, 197, 224, 0, - 0, 409, 458, 470, 0, 0, 0, 252, 0, 468, - 423, 597, 232, 283, 455, 429, 466, 437, 286, 0, - 0, 467, 369, 580, 447, 594, 621, 622, 262, 403, - 607, 517, 615, 639, 225, 259, 417, 502, 600, 491, - 394, 576, 577, 328, 490, 294, 201, 366, 627, 223, - 476, 368, 241, 230, 582, 604, 298, 288, 453, 634, - 212, 512, 592, 238, 480, 0, 0, 642, 246, 501, - 214, 589, 500, 390, 325, 326, 213, 0, 454, 267, - 292, 0, 0, 257, 412, 584, 585, 255, 643, 227, - 614, 219, 0, 613, 405, 579, 590, 391, 380, 218, - 588, 389, 379, 333, 352, 353, 279, 306, 444, 372, - 445, 305, 307, 401, 400, 402, 206, 601, 0, 207, - 0, 496, 603, 644, 449, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 302, 303, 312, 364, 416, 443, - 439, 448, 0, 574, 595, 608, 619, 625, 626, 628, - 629, 630, 631, 632, 635, 633, 404, 310, 492, 332, - 370, 0, 0, 422, 469, 239, 599, 493, 199, 0, - 0, 0, 0, 253, 254, 0, 570, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 659, 660, 661, 662, 640, 503, 509, 504, 505, 506, - 507, 508, 0, 510, 0, 0, 0, 0, 0, 395, - 0, 586, 587, 663, 381, 483, 596, 334, 346, 349, - 339, 358, 0, 359, 335, 336, 341, 343, 344, 345, - 350, 351, 355, 361, 248, 209, 387, 396, 573, 311, - 215, 216, 217, 519, 520, 521, 522, 611, 612, 616, - 204, 459, 460, 461, 462, 291, 606, 308, 465, 464, - 330, 331, 376, 446, 535, 537, 548, 552, 554, 556, - 562, 565, 536, 538, 549, 553, 555, 557, 563, 566, - 525, 527, 529, 531, 544, 543, 540, 568, 569, 546, - 551, 530, 542, 547, 560, 567, 564, 524, 528, 532, - 541, 559, 558, 539, 550, 561, 545, 533, 526, 534, - 0, 196, 220, 365, 94, 451, 287, 641, 610, 481, - 605, 205, 222, 0, 261, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 309, 317, - 318, 321, 327, 377, 383, 384, 385, 386, 406, 407, - 408, 411, 414, 415, 418, 420, 421, 424, 428, 432, - 433, 434, 436, 438, 440, 452, 457, 471, 472, 473, - 474, 475, 478, 479, 485, 486, 487, 488, 489, 497, - 498, 511, 581, 583, 598, 617, 623, 477, 300, 301, - 441, 442, 313, 314, 637, 638, 299, 593, 624, 591, - 636, 618, 435, 375, 0, 0, 378, 280, 304, 319, - 0, 609, 499, 226, 463, 289, 250, 0, 0, 210, - 245, 229, 258, 273, 276, 323, 388, 397, 426, 431, - 295, 270, 243, 456, 240, 482, 514, 515, 516, 518, - 392, 265, 430, 393, 0, 373, 571, 572, 315, 0, - 523, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 413, 0, 0, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 363, 266, 0, 0, - 427, 0, 203, 0, 484, 251, 374, 371, 578, 281, - 272, 268, 249, 316, 382, 425, 513, 419, 0, 367, - 0, 0, 494, 398, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 322, - 247, 324, 202, 410, 495, 285, 0, 95, 0, 0, - 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 348, 357, - 356, 337, 338, 340, 342, 347, 354, 360, 0, 0, - 602, 0, 0, 0, 264, 320, 271, 263, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 399, 256, 0, 450, - 0, 0, 0, 620, 0, 0, 0, 0, 0, 0, - 0, 362, 0, 329, 197, 224, 0, 0, 409, 458, - 470, 0, 0, 0, 252, 0, 468, 423, 597, 232, - 283, 455, 429, 466, 437, 286, 0, 0, 467, 369, - 580, 447, 594, 621, 622, 262, 403, 607, 517, 615, - 639, 225, 259, 417, 502, 600, 491, 394, 576, 577, - 328, 490, 294, 201, 366, 627, 223, 476, 368, 241, - 230, 582, 604, 298, 288, 453, 634, 212, 512, 592, - 238, 480, 0, 0, 642, 246, 501, 214, 589, 500, - 390, 325, 326, 213, 0, 454, 267, 292, 0, 0, - 257, 412, 584, 585, 255, 643, 227, 614, 219, 0, - 613, 405, 579, 590, 391, 380, 218, 588, 389, 379, - 333, 352, 353, 279, 306, 444, 372, 445, 305, 307, - 401, 400, 402, 206, 601, 0, 207, 0, 496, 603, - 644, 449, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 302, 303, 312, 364, 416, 443, 439, 448, 0, - 574, 595, 608, 619, 625, 626, 628, 629, 630, 631, - 632, 635, 633, 404, 310, 492, 332, 370, 0, 0, - 422, 469, 239, 599, 493, 199, 0, 0, 0, 0, - 253, 254, 0, 570, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, - 662, 640, 503, 509, 504, 505, 506, 507, 508, 0, - 510, 0, 0, 0, 0, 0, 395, 0, 586, 587, - 663, 381, 483, 596, 334, 346, 349, 339, 358, 0, - 359, 335, 336, 341, 343, 344, 345, 350, 351, 355, - 361, 248, 209, 387, 396, 573, 311, 215, 216, 217, - 519, 520, 521, 522, 611, 612, 616, 204, 459, 460, - 461, 462, 291, 606, 308, 465, 464, 330, 331, 376, - 446, 535, 537, 548, 552, 554, 556, 562, 565, 536, - 538, 549, 553, 555, 557, 563, 566, 525, 527, 529, - 531, 544, 543, 540, 568, 569, 546, 551, 530, 542, - 547, 560, 567, 564, 524, 528, 532, 541, 559, 558, - 539, 550, 561, 545, 533, 526, 534, 0, 196, 220, - 365, 0, 451, 287, 641, 610, 481, 605, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 2389, 0, - 0, 2388, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 309, 317, 318, 321, 327, - 377, 383, 384, 385, 386, 406, 407, 408, 411, 414, - 415, 418, 420, 421, 424, 428, 432, 433, 434, 436, - 438, 440, 452, 457, 471, 472, 473, 474, 475, 478, - 479, 485, 486, 487, 488, 489, 497, 498, 511, 581, - 583, 598, 617, 623, 477, 300, 301, 441, 442, 313, - 314, 637, 638, 299, 593, 624, 591, 636, 618, 435, - 375, 0, 0, 378, 280, 304, 319, 0, 609, 499, - 226, 463, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 323, 388, 397, 426, 431, 295, 270, 243, - 456, 240, 482, 514, 515, 516, 518, 392, 265, 430, - 393, 0, 373, 571, 572, 315, 0, 523, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 413, - 0, 0, 0, 2336, 0, 0, 0, 0, 269, 0, - 0, 0, 0, 363, 266, 0, 0, 427, 0, 203, - 0, 484, 251, 374, 371, 578, 281, 272, 268, 249, - 316, 382, 425, 513, 419, 0, 367, 0, 0, 494, - 398, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 322, 247, 324, 202, - 410, 495, 285, 0, 0, 0, 0, 1933, 194, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 348, 357, 356, 337, 338, - 340, 342, 347, 354, 360, 0, 0, 602, 0, 0, - 0, 264, 320, 271, 263, 575, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 399, 256, 0, 450, 0, 0, 0, - 620, 0, 0, 0, 0, 0, 0, 0, 362, 0, - 329, 197, 224, 0, 0, 409, 458, 470, 0, 0, - 0, 252, 0, 468, 423, 597, 232, 283, 455, 429, - 466, 437, 286, 0, 2334, 467, 369, 580, 447, 594, - 621, 622, 262, 403, 607, 517, 615, 639, 225, 259, - 417, 502, 600, 491, 394, 576, 577, 328, 490, 294, - 201, 366, 627, 223, 476, 368, 241, 230, 582, 604, - 298, 288, 453, 634, 212, 512, 592, 238, 480, 0, - 0, 642, 246, 501, 214, 589, 500, 390, 325, 326, - 213, 0, 454, 267, 292, 0, 0, 257, 412, 584, - 585, 255, 643, 227, 614, 219, 0, 613, 405, 579, - 590, 391, 380, 218, 588, 389, 379, 333, 352, 353, - 279, 306, 444, 372, 445, 305, 307, 401, 400, 402, - 206, 601, 0, 207, 0, 496, 603, 644, 449, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 302, 303, - 312, 364, 416, 443, 439, 448, 0, 574, 595, 608, - 619, 625, 626, 628, 629, 630, 631, 632, 635, 633, - 404, 310, 492, 332, 370, 0, 0, 422, 469, 239, - 599, 493, 199, 0, 0, 0, 0, 253, 254, 0, - 570, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 659, 660, 661, 662, 640, 503, - 509, 504, 505, 506, 507, 508, 0, 510, 0, 0, - 0, 0, 0, 395, 0, 586, 587, 663, 381, 483, - 596, 334, 346, 349, 339, 358, 0, 359, 335, 336, - 341, 343, 344, 345, 350, 351, 355, 361, 248, 209, - 387, 396, 573, 311, 215, 216, 217, 519, 520, 521, - 522, 611, 612, 616, 204, 459, 460, 461, 462, 291, - 606, 308, 465, 464, 330, 331, 376, 446, 535, 537, - 548, 552, 554, 556, 562, 565, 536, 538, 549, 553, - 555, 557, 563, 566, 525, 527, 529, 531, 544, 543, - 540, 568, 569, 546, 551, 530, 542, 547, 560, 567, - 564, 524, 528, 532, 541, 559, 558, 539, 550, 561, - 545, 533, 526, 534, 0, 196, 220, 365, 0, 451, - 287, 641, 610, 481, 605, 205, 222, 0, 261, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 309, 317, 318, 321, 327, 377, 383, 384, - 385, 386, 406, 407, 408, 411, 414, 415, 418, 420, - 421, 424, 428, 432, 433, 434, 436, 438, 440, 452, - 457, 471, 472, 473, 474, 475, 478, 479, 485, 486, - 487, 488, 489, 497, 498, 511, 581, 583, 598, 617, - 623, 477, 300, 301, 441, 442, 313, 314, 637, 638, - 299, 593, 624, 591, 636, 618, 435, 375, 0, 0, - 378, 280, 304, 319, 0, 609, 499, 226, 463, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 323, - 388, 397, 426, 431, 295, 270, 243, 456, 240, 482, - 514, 515, 516, 518, 392, 265, 430, 393, 0, 373, - 571, 572, 315, 0, 523, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 413, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 363, 266, 0, 0, 427, 0, 203, 0, 484, 251, - 374, 371, 578, 281, 272, 268, 249, 316, 382, 425, - 513, 419, 0, 367, 0, 0, 494, 398, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 322, 247, 324, 202, 410, 495, 285, - 0, 0, 0, 0, 0, 713, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 348, 357, 356, 337, 338, 340, 342, 347, - 354, 360, 0, 0, 602, 0, 0, 0, 264, 320, - 271, 263, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, - 0, 0, 0, 0, 0, 1079, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 399, 256, 0, 450, 0, 0, 0, 620, 0, 0, - 0, 0, 0, 0, 0, 362, 1085, 329, 197, 224, - 1083, 0, 409, 458, 470, 0, 0, 0, 252, 0, - 468, 423, 597, 232, 283, 455, 429, 466, 437, 286, - 0, 0, 467, 369, 580, 447, 594, 621, 622, 262, - 403, 607, 517, 615, 639, 225, 259, 417, 502, 600, - 491, 394, 576, 577, 328, 490, 294, 201, 366, 627, - 223, 476, 368, 241, 230, 582, 604, 298, 288, 453, - 634, 212, 512, 592, 238, 480, 0, 0, 642, 246, - 501, 214, 589, 500, 390, 325, 326, 213, 0, 454, - 267, 292, 0, 0, 257, 412, 584, 585, 255, 643, - 227, 614, 219, 0, 613, 405, 579, 590, 391, 380, - 218, 588, 389, 379, 333, 352, 353, 279, 306, 444, - 372, 445, 305, 307, 401, 400, 402, 206, 601, 0, - 207, 0, 496, 603, 644, 449, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 302, 303, 312, 364, 416, - 443, 439, 448, 0, 574, 595, 608, 619, 625, 626, - 628, 629, 630, 631, 632, 635, 633, 404, 310, 492, - 332, 370, 0, 0, 422, 469, 239, 599, 493, 199, - 0, 0, 0, 0, 253, 254, 0, 570, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 659, 660, 661, 662, 640, 503, 509, 504, 505, - 506, 507, 508, 0, 510, 0, 0, 0, 0, 0, - 395, 0, 586, 587, 663, 381, 483, 596, 334, 346, - 349, 339, 358, 0, 359, 335, 336, 341, 343, 344, - 345, 350, 351, 355, 361, 248, 209, 387, 396, 573, - 311, 215, 216, 217, 519, 520, 521, 522, 611, 612, - 616, 204, 459, 460, 461, 462, 291, 606, 308, 465, - 464, 330, 331, 376, 446, 535, 537, 548, 552, 554, - 556, 562, 565, 536, 538, 549, 553, 555, 557, 563, - 566, 525, 527, 529, 531, 544, 543, 540, 568, 569, - 546, 551, 530, 542, 547, 560, 567, 564, 524, 528, - 532, 541, 559, 558, 539, 550, 561, 545, 533, 526, - 534, 0, 196, 220, 365, 0, 451, 287, 641, 610, - 481, 605, 205, 222, 0, 261, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 309, - 317, 318, 321, 327, 377, 383, 384, 385, 386, 406, - 407, 408, 411, 414, 415, 418, 420, 421, 424, 428, - 432, 433, 434, 436, 438, 440, 452, 457, 471, 472, - 473, 474, 475, 478, 479, 485, 486, 487, 488, 489, - 497, 498, 511, 581, 583, 598, 617, 623, 477, 300, - 301, 441, 442, 313, 314, 637, 638, 299, 593, 624, - 591, 636, 618, 435, 375, 0, 0, 378, 280, 304, - 319, 0, 609, 499, 226, 463, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 323, 388, 397, 426, - 431, 295, 270, 243, 456, 240, 482, 514, 515, 516, - 518, 392, 265, 430, 393, 0, 373, 571, 572, 315, - 0, 523, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 413, 0, 0, 0, 2336, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 363, 266, 0, - 0, 427, 0, 203, 0, 484, 251, 374, 371, 578, - 281, 272, 268, 249, 316, 382, 425, 513, 419, 0, - 367, 0, 0, 494, 398, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 322, 247, 324, 202, 410, 495, 285, 0, 0, 0, - 0, 1933, 194, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 348, - 357, 356, 337, 338, 340, 342, 347, 354, 360, 0, - 0, 602, 0, 0, 0, 264, 320, 271, 263, 575, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 399, 256, 0, - 450, 0, 0, 0, 620, 0, 0, 0, 0, 0, - 0, 0, 362, 0, 329, 197, 224, 0, 0, 409, - 458, 470, 0, 0, 0, 252, 0, 468, 423, 597, - 232, 283, 455, 429, 466, 437, 286, 0, 0, 467, - 369, 580, 447, 594, 621, 622, 262, 403, 607, 517, - 615, 639, 225, 259, 417, 502, 600, 491, 394, 576, - 577, 328, 490, 294, 201, 366, 627, 223, 476, 368, - 241, 230, 582, 604, 298, 288, 453, 634, 212, 512, - 592, 238, 480, 0, 0, 642, 246, 501, 214, 589, - 500, 390, 325, 326, 213, 0, 454, 267, 292, 0, - 0, 257, 412, 584, 585, 255, 643, 227, 614, 219, - 0, 613, 405, 579, 590, 391, 380, 218, 588, 389, - 379, 333, 352, 353, 279, 306, 444, 372, 445, 305, - 307, 401, 400, 402, 206, 601, 0, 207, 0, 496, - 603, 644, 449, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 302, 303, 312, 364, 416, 443, 439, 448, - 0, 574, 595, 608, 619, 625, 626, 628, 629, 630, - 631, 632, 635, 633, 404, 310, 492, 332, 370, 0, - 0, 422, 469, 239, 599, 493, 199, 0, 0, 0, - 0, 253, 254, 0, 570, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, - 661, 662, 640, 503, 509, 504, 505, 506, 507, 508, - 0, 510, 0, 0, 0, 0, 0, 395, 0, 586, - 587, 663, 381, 483, 596, 334, 346, 349, 339, 358, - 0, 359, 335, 336, 341, 343, 344, 345, 350, 351, - 355, 361, 248, 209, 387, 396, 573, 311, 215, 216, - 217, 519, 520, 521, 522, 611, 612, 616, 204, 459, - 460, 461, 462, 291, 606, 308, 465, 464, 330, 331, - 376, 446, 535, 537, 548, 552, 554, 556, 562, 565, - 536, 538, 549, 553, 555, 557, 563, 566, 525, 527, - 529, 531, 544, 543, 540, 568, 569, 546, 551, 530, - 542, 547, 560, 567, 564, 524, 528, 532, 541, 559, - 558, 539, 550, 561, 545, 533, 526, 534, 0, 196, - 220, 365, 0, 451, 287, 641, 610, 481, 605, 205, - 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 309, 317, 318, 321, - 327, 377, 383, 384, 385, 386, 406, 407, 408, 411, - 414, 415, 418, 420, 421, 424, 428, 432, 433, 434, - 436, 438, 440, 452, 457, 471, 472, 473, 474, 475, - 478, 479, 485, 486, 487, 488, 489, 497, 498, 511, - 581, 583, 598, 617, 623, 477, 300, 301, 441, 442, - 313, 314, 637, 638, 299, 593, 624, 591, 636, 618, - 435, 375, 0, 0, 378, 280, 304, 319, 0, 609, - 499, 226, 463, 289, 250, 0, 0, 210, 245, 229, - 258, 273, 276, 323, 388, 397, 426, 431, 295, 270, - 243, 456, 240, 482, 514, 515, 516, 518, 392, 265, - 430, 393, 0, 373, 571, 572, 315, 0, 523, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 413, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 363, 266, 0, 0, 427, 0, - 203, 0, 484, 251, 374, 371, 578, 281, 272, 268, - 249, 316, 382, 425, 513, 419, 0, 367, 0, 0, - 494, 398, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 322, 247, 324, - 202, 410, 495, 285, 0, 0, 0, 1727, 0, 713, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 348, 357, 356, 337, - 338, 340, 342, 347, 354, 360, 0, 0, 602, 0, - 0, 0, 264, 320, 271, 263, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 399, 256, 0, 450, 0, 0, - 0, 620, 0, 0, 0, 3678, 0, 0, 0, 362, - 0, 329, 197, 224, 0, 0, 409, 458, 470, 0, - 0, 0, 252, 0, 468, 423, 597, 232, 283, 455, - 429, 466, 437, 286, 0, 0, 467, 369, 580, 447, - 594, 621, 622, 262, 403, 607, 517, 615, 639, 225, - 259, 417, 502, 600, 491, 394, 576, 577, 328, 490, - 294, 201, 366, 627, 223, 476, 368, 241, 230, 582, - 604, 298, 288, 453, 634, 212, 512, 592, 238, 480, - 0, 0, 642, 246, 501, 214, 589, 500, 390, 325, - 326, 213, 0, 454, 267, 292, 0, 0, 257, 412, - 584, 585, 255, 643, 227, 614, 219, 0, 613, 405, - 579, 590, 391, 380, 218, 588, 389, 379, 333, 352, - 353, 279, 306, 444, 372, 445, 305, 307, 401, 400, - 402, 206, 601, 0, 207, 0, 496, 603, 644, 449, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 302, - 303, 312, 364, 416, 443, 439, 448, 0, 574, 595, - 608, 619, 625, 626, 628, 629, 630, 631, 632, 635, - 633, 404, 310, 492, 332, 370, 0, 0, 422, 469, - 239, 599, 493, 199, 0, 0, 0, 0, 253, 254, - 0, 570, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 659, 660, 661, 662, 640, - 503, 509, 504, 505, 506, 507, 508, 0, 510, 0, - 0, 0, 0, 0, 395, 0, 586, 587, 663, 381, - 483, 596, 334, 346, 349, 339, 358, 0, 359, 335, - 336, 341, 343, 344, 345, 350, 351, 355, 361, 248, - 209, 387, 396, 573, 311, 215, 216, 217, 519, 520, - 521, 522, 611, 612, 616, 204, 459, 460, 461, 462, - 291, 606, 308, 465, 464, 330, 331, 376, 446, 535, - 537, 548, 552, 554, 556, 562, 565, 536, 538, 549, - 553, 555, 557, 563, 566, 525, 527, 529, 531, 544, - 543, 540, 568, 569, 546, 551, 530, 542, 547, 560, - 567, 564, 524, 528, 532, 541, 559, 558, 539, 550, - 561, 545, 533, 526, 534, 0, 196, 220, 365, 0, - 451, 287, 641, 610, 481, 605, 205, 222, 0, 261, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 309, 317, 318, 321, 327, 377, 383, - 384, 385, 386, 406, 407, 408, 411, 414, 415, 418, - 420, 421, 424, 428, 432, 433, 434, 436, 438, 440, - 452, 457, 471, 472, 473, 474, 475, 478, 479, 485, - 486, 487, 488, 489, 497, 498, 511, 581, 583, 598, - 617, 623, 477, 300, 301, 441, 442, 313, 314, 637, - 638, 299, 593, 624, 591, 636, 618, 435, 375, 0, - 0, 378, 280, 304, 319, 0, 609, 499, 226, 463, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 323, 388, 397, 426, 431, 295, 270, 243, 456, 240, - 482, 514, 515, 516, 518, 392, 265, 430, 393, 0, - 373, 571, 572, 315, 0, 523, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 413, 0, 0, - 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 363, 266, 0, 0, 427, 0, 203, 0, 484, - 251, 374, 371, 578, 281, 272, 268, 249, 316, 382, - 425, 513, 419, 0, 367, 0, 0, 494, 398, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 322, 247, 324, 202, 410, 495, - 285, 0, 0, 0, 0, 2097, 713, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 348, 357, 356, 337, 338, 340, 342, - 347, 354, 360, 0, 0, 602, 0, 0, 0, 264, - 320, 271, 263, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2098, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 399, 256, 0, 450, 0, 0, 0, 620, 0, - 0, 0, 0, 0, 0, 0, 362, 0, 329, 197, - 224, 0, 0, 409, 458, 470, 0, 0, 0, 252, - 0, 468, 423, 597, 232, 283, 455, 429, 466, 437, - 286, 0, 0, 467, 369, 580, 447, 594, 621, 622, - 262, 403, 607, 517, 615, 639, 225, 259, 417, 502, - 600, 491, 394, 576, 577, 328, 490, 294, 201, 366, - 627, 223, 476, 368, 241, 230, 582, 604, 298, 288, - 453, 634, 212, 512, 592, 238, 480, 0, 0, 642, - 246, 501, 214, 589, 500, 390, 325, 326, 213, 0, - 454, 267, 292, 0, 0, 257, 412, 584, 585, 255, - 643, 227, 614, 219, 0, 613, 405, 579, 590, 391, - 380, 218, 588, 389, 379, 333, 352, 353, 279, 306, - 444, 372, 445, 305, 307, 401, 400, 402, 206, 601, - 0, 207, 0, 496, 603, 644, 449, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 302, 303, 312, 364, - 416, 443, 439, 448, 0, 574, 595, 608, 619, 625, - 626, 628, 629, 630, 631, 632, 635, 633, 404, 310, - 492, 332, 370, 0, 0, 422, 469, 239, 599, 493, - 199, 0, 0, 0, 0, 253, 254, 0, 570, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 659, 660, 661, 662, 640, 503, 509, 504, - 505, 506, 507, 508, 0, 510, 0, 0, 0, 0, - 0, 395, 0, 586, 587, 663, 381, 483, 596, 334, - 346, 349, 339, 358, 0, 359, 335, 336, 341, 343, - 344, 345, 350, 351, 355, 361, 248, 209, 387, 396, - 573, 311, 215, 216, 217, 519, 520, 521, 522, 611, - 612, 616, 204, 459, 460, 461, 462, 291, 606, 308, - 465, 464, 330, 331, 376, 446, 535, 537, 548, 552, - 554, 556, 562, 565, 536, 538, 549, 553, 555, 557, - 563, 566, 525, 527, 529, 531, 544, 543, 540, 568, - 569, 546, 551, 530, 542, 547, 560, 567, 564, 524, - 528, 532, 541, 559, 558, 539, 550, 561, 545, 533, - 526, 534, 0, 196, 220, 365, 0, 451, 287, 641, - 610, 481, 605, 205, 222, 0, 261, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 309, 317, 318, 321, 327, 377, 383, 384, 385, 386, - 406, 407, 408, 411, 414, 415, 418, 420, 421, 424, - 428, 432, 433, 434, 436, 438, 440, 452, 457, 471, - 472, 473, 474, 475, 478, 479, 485, 486, 487, 488, - 489, 497, 498, 511, 581, 583, 598, 617, 623, 477, - 300, 301, 441, 442, 313, 314, 637, 638, 299, 593, - 624, 591, 636, 618, 435, 375, 0, 0, 378, 280, - 304, 319, 0, 609, 499, 226, 463, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 323, 388, 397, - 426, 431, 295, 270, 243, 456, 240, 482, 514, 515, - 516, 518, 392, 265, 430, 393, 0, 373, 571, 572, - 315, 0, 523, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 413, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 363, 266, - 0, 0, 427, 0, 203, 0, 484, 251, 374, 371, - 578, 281, 272, 268, 249, 316, 382, 425, 513, 419, - 0, 367, 0, 0, 494, 398, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 322, 247, 324, 202, 410, 495, 285, 0, 0, - 0, 0, 2833, 713, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 348, 357, 356, 337, 338, 340, 342, 347, 354, 360, - 0, 0, 602, 0, 0, 0, 264, 320, 271, 263, - 575, 0, 0, 0, 0, 0, 0, 0, 0, 228, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2834, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 399, 256, - 0, 450, 0, 0, 0, 620, 0, 0, 0, 0, - 0, 0, 0, 362, 0, 329, 197, 224, 0, 0, - 409, 458, 470, 0, 0, 0, 252, 0, 468, 423, - 597, 232, 283, 455, 429, 466, 437, 286, 0, 0, - 467, 369, 580, 447, 594, 621, 622, 262, 403, 607, - 517, 615, 639, 225, 259, 417, 502, 600, 491, 394, - 576, 577, 328, 490, 294, 201, 366, 627, 223, 476, - 368, 241, 230, 582, 604, 298, 288, 453, 634, 212, - 512, 592, 238, 480, 0, 0, 642, 246, 501, 214, - 589, 500, 390, 325, 326, 213, 0, 454, 267, 292, - 0, 0, 257, 412, 584, 585, 255, 643, 227, 614, - 219, 0, 613, 405, 579, 590, 391, 380, 218, 588, - 389, 379, 333, 352, 353, 279, 306, 444, 372, 445, - 305, 307, 401, 400, 402, 206, 601, 0, 207, 0, - 496, 603, 644, 449, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 302, 303, 312, 364, 416, 443, 439, - 448, 0, 574, 595, 608, 619, 625, 626, 628, 629, - 630, 631, 632, 635, 633, 404, 310, 492, 332, 370, - 0, 0, 422, 469, 239, 599, 493, 199, 0, 0, - 0, 0, 253, 254, 0, 570, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, - 660, 661, 662, 640, 503, 509, 504, 505, 506, 507, - 508, 0, 510, 0, 0, 0, 0, 0, 395, 0, - 586, 587, 663, 381, 483, 596, 334, 346, 349, 339, - 358, 0, 359, 335, 336, 341, 343, 344, 345, 350, - 351, 355, 361, 248, 209, 387, 396, 573, 311, 215, - 216, 217, 519, 520, 521, 522, 611, 612, 616, 204, - 459, 460, 461, 462, 291, 606, 308, 465, 464, 330, - 331, 376, 446, 535, 537, 548, 552, 554, 556, 562, - 565, 536, 538, 549, 553, 555, 557, 563, 566, 525, - 527, 529, 531, 544, 543, 540, 568, 569, 546, 551, - 530, 542, 547, 560, 567, 564, 524, 528, 532, 541, - 559, 558, 539, 550, 561, 545, 533, 526, 534, 0, - 196, 220, 365, 0, 451, 287, 641, 610, 481, 605, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 309, 317, 318, - 321, 327, 377, 383, 384, 385, 386, 406, 407, 408, - 411, 414, 415, 418, 420, 421, 424, 428, 432, 433, - 434, 436, 438, 440, 452, 457, 471, 472, 473, 474, - 475, 478, 479, 485, 486, 487, 488, 489, 497, 498, - 511, 581, 583, 598, 617, 623, 477, 300, 301, 441, - 442, 313, 314, 637, 638, 299, 593, 624, 591, 636, - 618, 435, 375, 0, 0, 378, 280, 304, 319, 0, - 609, 499, 226, 463, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 323, 388, 397, 426, 431, 295, - 270, 243, 456, 240, 482, 514, 515, 516, 518, 392, - 265, 430, 393, 0, 373, 571, 572, 315, 0, 523, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 413, 0, 0, 0, 0, 0, 0, 0, 0, - 269, 0, 0, 0, 0, 363, 266, 0, 0, 427, - 0, 203, 0, 484, 251, 374, 371, 578, 281, 272, - 268, 249, 316, 382, 425, 513, 419, 0, 367, 0, - 0, 494, 398, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 322, 247, - 324, 202, 410, 495, 285, 0, 0, 0, 0, 0, - 713, 0, 0, 0, 0, 2818, 0, 0, 0, 0, - 237, 0, 0, 244, 2819, 0, 0, 348, 357, 356, - 337, 338, 340, 342, 347, 354, 360, 0, 0, 602, - 0, 0, 0, 264, 320, 271, 263, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 399, 256, 0, 450, 0, - 0, 0, 620, 0, 0, 0, 0, 0, 0, 0, - 362, 0, 329, 197, 224, 0, 0, 409, 458, 470, - 0, 0, 0, 252, 0, 468, 423, 597, 232, 283, - 455, 429, 466, 437, 286, 0, 0, 467, 369, 580, - 447, 594, 621, 622, 262, 403, 607, 517, 615, 639, - 225, 259, 417, 502, 600, 491, 394, 576, 577, 328, - 490, 294, 201, 366, 627, 223, 476, 368, 241, 230, - 582, 604, 298, 288, 453, 634, 212, 512, 592, 238, - 480, 0, 0, 642, 246, 501, 214, 589, 500, 390, - 325, 326, 213, 0, 454, 267, 292, 0, 0, 257, - 412, 584, 585, 255, 643, 227, 614, 219, 0, 613, - 405, 579, 590, 391, 380, 218, 588, 389, 379, 333, - 352, 353, 279, 306, 444, 372, 445, 305, 307, 401, - 400, 402, 206, 601, 0, 207, 0, 496, 603, 644, - 449, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 302, 303, 312, 364, 416, 443, 439, 448, 0, 574, - 595, 608, 619, 625, 626, 628, 629, 630, 631, 632, - 635, 633, 404, 310, 492, 332, 370, 0, 0, 422, - 469, 239, 599, 493, 199, 0, 0, 0, 0, 253, - 254, 0, 570, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, - 640, 503, 509, 504, 505, 506, 507, 508, 0, 510, - 0, 0, 0, 0, 0, 395, 0, 586, 587, 663, - 381, 483, 596, 334, 346, 349, 339, 358, 0, 359, - 335, 336, 341, 343, 344, 345, 350, 351, 355, 361, - 248, 209, 387, 396, 573, 311, 215, 216, 217, 519, - 520, 521, 522, 611, 612, 616, 204, 459, 460, 461, - 462, 291, 606, 308, 465, 464, 330, 331, 376, 446, - 535, 537, 548, 552, 554, 556, 562, 565, 536, 538, - 549, 553, 555, 557, 563, 566, 525, 527, 529, 531, - 544, 543, 540, 568, 569, 546, 551, 530, 542, 547, - 560, 567, 564, 524, 528, 532, 541, 559, 558, 539, - 550, 561, 545, 533, 526, 534, 0, 196, 220, 365, - 0, 451, 287, 641, 610, 481, 605, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 309, 317, 318, 321, 327, 377, - 383, 384, 385, 386, 406, 407, 408, 411, 414, 415, - 418, 420, 421, 424, 428, 432, 433, 434, 436, 438, - 440, 452, 457, 471, 472, 473, 474, 475, 478, 479, - 485, 486, 487, 488, 489, 497, 498, 511, 581, 583, - 598, 617, 623, 477, 300, 301, 441, 442, 313, 314, - 637, 638, 299, 593, 624, 591, 636, 618, 435, 375, - 0, 0, 378, 280, 304, 319, 0, 609, 499, 226, - 463, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 323, 388, 397, 426, 431, 295, 270, 243, 456, - 240, 482, 514, 515, 516, 518, 392, 265, 430, 393, - 0, 373, 571, 572, 315, 0, 523, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 413, 0, - 0, 0, 0, 0, 0, 0, 0, 269, 1773, 0, - 0, 0, 363, 266, 0, 0, 427, 0, 203, 0, - 484, 251, 374, 371, 578, 281, 272, 268, 249, 316, - 382, 425, 513, 419, 0, 367, 0, 0, 494, 398, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 322, 247, 324, 202, 410, - 495, 285, 0, 0, 0, 0, 1772, 713, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 348, 357, 356, 337, 338, 340, - 342, 347, 354, 360, 0, 0, 602, 0, 0, 0, - 264, 320, 271, 263, 575, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 399, 256, 0, 450, 0, 0, 0, 620, - 0, 0, 0, 0, 0, 0, 0, 362, 0, 329, - 197, 224, 0, 0, 409, 458, 470, 0, 0, 0, - 252, 0, 468, 423, 597, 232, 283, 455, 429, 466, - 437, 286, 0, 0, 467, 369, 580, 447, 594, 621, - 622, 262, 403, 607, 517, 615, 639, 225, 259, 417, - 502, 600, 491, 394, 576, 577, 328, 490, 294, 201, - 366, 627, 223, 476, 368, 241, 230, 582, 604, 298, - 288, 453, 634, 212, 512, 592, 238, 480, 0, 0, - 642, 246, 501, 214, 589, 500, 390, 325, 326, 213, - 0, 454, 267, 292, 0, 0, 257, 412, 584, 585, - 255, 643, 227, 614, 219, 0, 613, 405, 579, 590, - 391, 380, 218, 588, 389, 379, 333, 352, 353, 279, - 306, 444, 372, 445, 305, 307, 401, 400, 402, 206, - 601, 0, 207, 0, 496, 603, 644, 449, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 302, 303, 312, - 364, 416, 443, 439, 448, 0, 574, 595, 608, 619, - 625, 626, 628, 629, 630, 631, 632, 635, 633, 404, - 310, 492, 332, 370, 0, 0, 422, 469, 239, 599, - 493, 199, 0, 0, 0, 0, 253, 254, 0, 570, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 659, 660, 661, 662, 640, 503, 509, - 504, 505, 506, 507, 508, 0, 510, 0, 0, 0, - 0, 0, 395, 0, 586, 587, 663, 381, 483, 596, - 334, 346, 349, 339, 358, 0, 359, 335, 336, 341, - 343, 344, 345, 350, 351, 355, 361, 248, 209, 387, - 396, 573, 311, 215, 216, 217, 519, 520, 521, 522, - 611, 612, 616, 204, 459, 460, 461, 462, 291, 606, - 308, 465, 464, 330, 331, 376, 446, 535, 537, 548, - 552, 554, 556, 562, 565, 536, 538, 549, 553, 555, - 557, 563, 566, 525, 527, 529, 531, 544, 543, 540, - 568, 569, 546, 551, 530, 542, 547, 560, 567, 564, - 524, 528, 532, 541, 559, 558, 539, 550, 561, 545, - 533, 526, 534, 0, 196, 220, 365, 0, 451, 287, - 641, 610, 481, 605, 205, 222, 0, 261, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 309, 317, 318, 321, 327, 377, 383, 384, 385, - 386, 406, 407, 408, 411, 414, 415, 418, 420, 421, - 424, 428, 432, 433, 434, 436, 438, 440, 452, 457, - 471, 472, 473, 474, 475, 478, 479, 485, 486, 487, - 488, 489, 497, 498, 511, 581, 583, 598, 617, 623, - 477, 300, 301, 441, 442, 313, 314, 637, 638, 299, - 593, 624, 591, 636, 618, 435, 375, 0, 0, 378, - 280, 304, 319, 0, 609, 499, 226, 463, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 323, 388, - 397, 426, 431, 295, 270, 243, 456, 240, 482, 514, - 515, 516, 518, 392, 265, 430, 393, 0, 373, 571, - 572, 315, 0, 523, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 413, 0, 0, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 363, - 266, 0, 0, 427, 0, 203, 0, 484, 251, 374, - 371, 578, 281, 272, 268, 249, 316, 382, 425, 513, - 419, 0, 367, 0, 0, 494, 398, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 322, 247, 324, 202, 410, 495, 285, 0, - 0, 0, 0, 0, 715, 716, 717, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 348, 357, 356, 337, 338, 340, 342, 347, 354, - 360, 0, 0, 602, 0, 0, 0, 264, 320, 271, - 263, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 399, - 256, 0, 450, 0, 0, 0, 620, 0, 0, 0, - 0, 0, 0, 0, 362, 0, 329, 197, 224, 0, - 0, 409, 458, 470, 0, 0, 0, 252, 0, 468, - 423, 597, 232, 283, 455, 429, 466, 437, 286, 0, - 0, 467, 369, 580, 447, 594, 621, 622, 262, 403, - 607, 517, 615, 639, 225, 259, 417, 502, 600, 491, - 394, 576, 577, 328, 490, 294, 201, 366, 627, 223, - 476, 368, 241, 230, 582, 604, 298, 288, 453, 634, - 212, 512, 592, 238, 480, 0, 0, 642, 246, 501, - 214, 589, 500, 390, 325, 326, 213, 0, 454, 267, - 292, 0, 0, 257, 412, 584, 585, 255, 643, 227, - 614, 219, 0, 613, 405, 579, 590, 391, 380, 218, - 588, 389, 379, 333, 352, 353, 279, 306, 444, 372, - 445, 305, 307, 401, 400, 402, 206, 601, 0, 207, - 0, 496, 603, 644, 449, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 302, 303, 312, 364, 416, 443, - 439, 448, 0, 574, 595, 608, 619, 625, 626, 628, - 629, 630, 631, 632, 635, 633, 404, 310, 492, 332, - 370, 0, 0, 422, 469, 239, 599, 493, 199, 0, - 0, 0, 0, 253, 254, 0, 570, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 659, 660, 661, 662, 640, 503, 509, 504, 505, 506, - 507, 508, 0, 510, 0, 0, 0, 0, 0, 395, - 0, 586, 587, 663, 381, 483, 596, 334, 346, 349, - 339, 358, 0, 359, 335, 336, 341, 343, 344, 345, - 350, 351, 355, 361, 248, 209, 387, 396, 573, 311, - 215, 216, 217, 519, 520, 521, 522, 611, 612, 616, - 204, 459, 460, 461, 462, 291, 606, 308, 465, 464, - 330, 331, 376, 446, 535, 537, 548, 552, 554, 556, - 562, 565, 536, 538, 549, 553, 555, 557, 563, 566, - 525, 527, 529, 531, 544, 543, 540, 568, 569, 546, - 551, 530, 542, 547, 560, 567, 564, 524, 528, 532, - 541, 559, 558, 539, 550, 561, 545, 533, 526, 534, - 0, 196, 220, 365, 0, 451, 287, 641, 610, 481, - 605, 205, 222, 0, 261, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 309, 317, - 318, 321, 327, 377, 383, 384, 385, 386, 406, 407, - 408, 411, 414, 415, 418, 420, 421, 424, 428, 432, - 433, 434, 436, 438, 440, 452, 457, 471, 472, 473, - 474, 475, 478, 479, 485, 486, 487, 488, 489, 497, - 498, 511, 581, 583, 598, 617, 623, 477, 300, 301, - 441, 442, 313, 314, 637, 638, 299, 593, 624, 591, - 636, 618, 435, 375, 0, 0, 378, 280, 304, 319, - 0, 609, 499, 226, 463, 289, 250, 0, 0, 210, - 245, 229, 258, 273, 276, 323, 388, 397, 426, 431, - 295, 270, 243, 456, 240, 482, 514, 515, 516, 518, - 392, 265, 430, 393, 0, 373, 571, 572, 315, 0, - 523, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 413, 0, 0, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 363, 266, 0, 0, - 427, 0, 203, 0, 484, 251, 374, 371, 578, 281, - 272, 268, 249, 316, 382, 425, 513, 419, 0, 367, - 0, 0, 494, 398, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 322, - 247, 324, 202, 410, 495, 285, 0, 0, 0, 0, - 0, 713, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 348, 357, - 356, 337, 338, 340, 342, 347, 354, 360, 0, 0, - 602, 0, 0, 0, 264, 320, 271, 263, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 399, 256, 0, 450, - 0, 0, 0, 620, 0, 0, 0, 4020, 0, 0, - 0, 362, 0, 329, 197, 224, 0, 0, 409, 458, - 470, 0, 0, 0, 252, 0, 468, 423, 597, 232, - 283, 455, 429, 466, 437, 286, 0, 0, 467, 369, - 580, 447, 594, 621, 622, 262, 403, 607, 517, 615, - 639, 225, 259, 417, 502, 600, 491, 394, 576, 577, - 328, 490, 294, 201, 366, 627, 223, 476, 368, 241, - 230, 582, 604, 298, 288, 453, 634, 212, 512, 592, - 238, 480, 0, 0, 642, 246, 501, 214, 589, 500, - 390, 325, 326, 213, 0, 454, 267, 292, 0, 0, - 257, 412, 584, 585, 255, 643, 227, 614, 219, 0, - 613, 405, 579, 590, 391, 380, 218, 588, 389, 379, - 333, 352, 353, 279, 306, 444, 372, 445, 305, 307, - 401, 400, 402, 206, 601, 0, 207, 0, 496, 603, - 644, 449, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 302, 303, 312, 364, 416, 443, 439, 448, 0, - 574, 595, 608, 619, 625, 626, 628, 629, 630, 631, - 632, 635, 633, 404, 310, 492, 332, 370, 0, 0, - 422, 469, 239, 599, 493, 199, 0, 0, 0, 0, - 253, 254, 0, 570, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, - 662, 640, 503, 509, 504, 505, 506, 507, 508, 0, - 510, 0, 0, 0, 0, 0, 395, 0, 586, 587, - 663, 381, 483, 596, 334, 346, 349, 339, 358, 0, - 359, 335, 336, 341, 343, 344, 345, 350, 351, 355, - 361, 248, 209, 387, 396, 573, 311, 215, 216, 217, - 519, 520, 521, 522, 611, 612, 616, 204, 459, 460, - 461, 462, 291, 606, 308, 465, 464, 330, 331, 376, - 446, 535, 537, 548, 552, 554, 556, 562, 565, 536, - 538, 549, 553, 555, 557, 563, 566, 525, 527, 529, - 531, 544, 543, 540, 568, 569, 546, 551, 530, 542, - 547, 560, 567, 564, 524, 528, 532, 541, 559, 558, - 539, 550, 561, 545, 533, 526, 534, 0, 196, 220, - 365, 0, 451, 287, 641, 610, 481, 605, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 309, 317, 318, 321, 327, - 377, 383, 384, 385, 386, 406, 407, 408, 411, 414, - 415, 418, 420, 421, 424, 428, 432, 433, 434, 436, - 438, 440, 452, 457, 471, 472, 473, 474, 475, 478, - 479, 485, 486, 487, 488, 489, 497, 498, 511, 581, - 583, 598, 617, 623, 477, 300, 301, 441, 442, 313, - 314, 637, 638, 299, 593, 624, 591, 636, 618, 435, - 375, 0, 0, 378, 280, 304, 319, 0, 609, 499, - 226, 463, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 323, 388, 397, 426, 431, 295, 270, 243, - 456, 240, 482, 514, 515, 516, 518, 392, 265, 430, - 393, 0, 373, 571, 572, 315, 0, 523, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 413, - 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, - 0, 0, 0, 363, 266, 0, 0, 427, 0, 203, - 0, 484, 251, 374, 371, 578, 281, 272, 268, 249, - 316, 382, 425, 513, 419, 0, 367, 0, 0, 494, - 398, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 322, 247, 324, 202, - 410, 495, 285, 0, 0, 0, 0, 1933, 194, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 348, 357, 356, 337, 338, - 340, 342, 347, 354, 360, 0, 0, 602, 0, 0, - 0, 264, 320, 271, 263, 575, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 399, 256, 0, 450, 0, 0, 0, - 620, 0, 0, 0, 0, 0, 0, 0, 362, 0, - 329, 197, 224, 0, 0, 409, 458, 470, 0, 0, - 0, 252, 0, 468, 423, 597, 232, 283, 455, 429, - 466, 437, 286, 0, 0, 467, 369, 580, 447, 594, - 621, 622, 262, 403, 607, 517, 615, 639, 225, 259, - 417, 502, 600, 491, 394, 576, 577, 328, 490, 294, - 201, 366, 627, 223, 476, 368, 241, 230, 582, 604, - 298, 288, 453, 634, 212, 512, 592, 238, 480, 0, - 0, 642, 246, 501, 214, 589, 500, 390, 325, 326, - 213, 0, 454, 267, 292, 0, 0, 257, 412, 584, - 585, 255, 643, 227, 614, 219, 0, 613, 405, 579, - 590, 391, 380, 218, 588, 389, 379, 333, 352, 353, - 279, 306, 444, 372, 445, 305, 307, 401, 400, 402, - 206, 601, 0, 207, 0, 496, 603, 644, 449, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 302, 303, - 312, 364, 416, 443, 439, 448, 0, 574, 595, 608, - 619, 625, 626, 628, 629, 630, 631, 632, 635, 633, - 404, 310, 492, 332, 370, 0, 0, 422, 469, 239, - 599, 493, 199, 0, 0, 0, 0, 253, 254, 0, - 570, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 659, 660, 661, 662, 640, 503, - 509, 504, 505, 506, 507, 508, 0, 510, 0, 0, - 0, 0, 0, 395, 0, 586, 587, 663, 381, 483, - 596, 334, 346, 349, 339, 358, 0, 359, 335, 336, - 341, 343, 344, 345, 350, 351, 355, 361, 248, 209, - 387, 396, 573, 311, 215, 216, 217, 519, 520, 521, - 522, 611, 612, 616, 204, 459, 460, 461, 462, 291, - 606, 308, 465, 464, 330, 331, 376, 446, 535, 537, - 548, 552, 554, 556, 562, 565, 536, 538, 549, 553, - 555, 557, 563, 566, 525, 527, 529, 531, 544, 543, - 540, 568, 569, 546, 551, 530, 542, 547, 560, 567, - 564, 524, 528, 532, 541, 559, 558, 539, 550, 561, - 545, 533, 526, 534, 0, 196, 220, 365, 0, 451, - 287, 641, 610, 481, 605, 205, 222, 0, 261, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 309, 317, 318, 321, 327, 377, 383, 384, - 385, 386, 406, 407, 408, 411, 414, 415, 418, 420, - 421, 424, 428, 432, 433, 434, 436, 438, 440, 452, - 457, 471, 472, 473, 474, 475, 478, 479, 485, 486, - 487, 488, 489, 497, 498, 511, 581, 583, 598, 617, - 623, 477, 300, 301, 441, 442, 313, 314, 637, 638, - 299, 593, 624, 591, 636, 618, 435, 375, 0, 0, - 378, 280, 304, 319, 0, 609, 499, 226, 463, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 323, - 388, 397, 426, 431, 295, 270, 243, 456, 240, 482, - 514, 515, 516, 518, 392, 265, 430, 393, 0, 373, - 571, 572, 315, 0, 523, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 413, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 363, 266, 0, 0, 427, 0, 203, 0, 484, 251, - 374, 371, 578, 281, 272, 268, 249, 316, 382, 425, - 513, 419, 0, 367, 0, 0, 494, 398, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 322, 247, 324, 202, 410, 495, 285, - 0, 0, 0, 0, 0, 713, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 348, 357, 356, 337, 338, 340, 342, 347, - 354, 360, 0, 0, 602, 0, 0, 0, 264, 320, - 271, 263, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 399, 256, 0, 450, 0, 0, 0, 620, 0, 0, - 0, 3678, 0, 0, 0, 362, 0, 329, 197, 224, - 0, 0, 409, 458, 470, 0, 0, 0, 252, 0, - 468, 423, 597, 232, 283, 455, 429, 466, 437, 286, - 0, 0, 467, 369, 580, 447, 594, 621, 622, 262, - 403, 607, 517, 615, 639, 225, 259, 417, 502, 600, - 491, 394, 576, 577, 328, 490, 294, 201, 366, 627, - 223, 476, 368, 241, 230, 582, 604, 298, 288, 453, - 634, 212, 512, 592, 238, 480, 0, 0, 642, 246, - 501, 214, 589, 500, 390, 325, 326, 213, 0, 454, - 267, 292, 0, 0, 257, 412, 584, 585, 255, 643, - 227, 614, 219, 0, 613, 405, 579, 590, 391, 380, - 218, 588, 389, 379, 333, 352, 353, 279, 306, 444, - 372, 445, 305, 307, 401, 400, 402, 206, 601, 0, - 207, 0, 496, 603, 644, 449, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 302, 303, 312, 364, 416, - 443, 439, 448, 0, 574, 595, 608, 619, 625, 626, - 628, 629, 630, 631, 632, 635, 633, 404, 310, 492, - 332, 370, 0, 0, 422, 469, 239, 599, 493, 199, - 0, 0, 0, 0, 253, 254, 0, 570, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 659, 660, 661, 662, 640, 503, 509, 504, 505, - 506, 507, 508, 0, 510, 0, 0, 0, 0, 0, - 395, 0, 586, 587, 663, 381, 483, 596, 334, 346, - 349, 339, 358, 0, 359, 335, 336, 341, 343, 344, - 345, 350, 351, 355, 361, 248, 209, 387, 396, 573, - 311, 215, 216, 217, 519, 520, 521, 522, 611, 612, - 616, 204, 459, 460, 461, 462, 291, 606, 308, 465, - 464, 330, 331, 376, 446, 535, 537, 548, 552, 554, - 556, 562, 565, 536, 538, 549, 553, 555, 557, 563, - 566, 525, 527, 529, 531, 544, 543, 540, 568, 569, - 546, 551, 530, 542, 547, 560, 567, 564, 524, 528, - 532, 541, 559, 558, 539, 550, 561, 545, 533, 526, - 534, 0, 196, 220, 365, 0, 451, 287, 641, 610, - 481, 605, 205, 222, 0, 261, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 309, - 317, 318, 321, 327, 377, 383, 384, 385, 386, 406, - 407, 408, 411, 414, 415, 418, 420, 421, 424, 428, - 432, 433, 434, 436, 438, 440, 452, 457, 471, 472, - 473, 474, 475, 478, 479, 485, 486, 487, 488, 489, - 497, 498, 511, 581, 583, 598, 617, 623, 477, 300, - 301, 441, 442, 313, 314, 637, 638, 299, 593, 624, - 591, 636, 618, 435, 375, 0, 0, 378, 280, 304, - 319, 0, 609, 499, 226, 463, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 323, 388, 397, 426, - 431, 295, 270, 243, 456, 240, 482, 514, 515, 516, - 518, 392, 265, 430, 393, 0, 373, 571, 572, 315, - 0, 523, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 413, 0, 0, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 363, 266, 0, - 0, 427, 0, 203, 0, 484, 251, 374, 371, 578, - 281, 272, 268, 249, 316, 382, 425, 513, 419, 0, - 367, 0, 0, 494, 398, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 322, 247, 324, 202, 410, 495, 285, 0, 95, 0, - 0, 0, 713, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 348, - 357, 356, 337, 338, 340, 342, 347, 354, 360, 0, - 0, 602, 0, 0, 0, 264, 320, 271, 263, 575, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 399, 256, 0, - 450, 0, 0, 0, 620, 0, 0, 0, 0, 0, - 0, 0, 362, 0, 329, 197, 224, 0, 0, 409, - 458, 470, 0, 0, 0, 252, 0, 468, 423, 597, - 232, 283, 455, 429, 466, 437, 286, 0, 0, 467, - 369, 580, 447, 594, 621, 622, 262, 403, 607, 517, - 615, 639, 225, 259, 417, 502, 600, 491, 394, 576, - 577, 328, 490, 294, 201, 366, 627, 223, 476, 368, - 241, 230, 582, 604, 298, 288, 453, 634, 212, 512, - 592, 238, 480, 0, 0, 642, 246, 501, 214, 589, - 500, 390, 325, 326, 213, 0, 454, 267, 292, 0, - 0, 257, 412, 584, 585, 255, 643, 227, 614, 219, - 0, 613, 405, 579, 590, 391, 380, 218, 588, 389, - 379, 333, 352, 353, 279, 306, 444, 372, 445, 305, - 307, 401, 400, 402, 206, 601, 0, 207, 0, 496, - 603, 644, 449, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 302, 303, 312, 364, 416, 443, 439, 448, - 0, 574, 595, 608, 619, 625, 626, 628, 629, 630, - 631, 632, 635, 633, 404, 310, 492, 332, 370, 0, - 0, 422, 469, 239, 599, 493, 199, 0, 0, 0, - 0, 253, 254, 0, 570, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, - 661, 662, 640, 503, 509, 504, 505, 506, 507, 508, - 0, 510, 0, 0, 0, 0, 0, 395, 0, 586, - 587, 663, 381, 483, 596, 334, 346, 349, 339, 358, - 0, 359, 335, 336, 341, 343, 344, 345, 350, 351, - 355, 361, 248, 209, 387, 396, 573, 311, 215, 216, - 217, 519, 520, 521, 522, 611, 612, 616, 204, 459, - 460, 461, 462, 291, 606, 308, 465, 464, 330, 331, - 376, 446, 535, 537, 548, 552, 554, 556, 562, 565, - 536, 538, 549, 553, 555, 557, 563, 566, 525, 527, - 529, 531, 544, 543, 540, 568, 569, 546, 551, 530, - 542, 547, 560, 567, 564, 524, 528, 532, 541, 559, - 558, 539, 550, 561, 545, 533, 526, 534, 0, 196, - 220, 365, 0, 451, 287, 641, 610, 481, 605, 205, - 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 309, 317, 318, 321, - 327, 377, 383, 384, 385, 386, 406, 407, 408, 411, - 414, 415, 418, 420, 421, 424, 428, 432, 433, 434, - 436, 438, 440, 452, 457, 471, 472, 473, 474, 475, - 478, 479, 485, 486, 487, 488, 489, 497, 498, 511, - 581, 583, 598, 617, 623, 477, 300, 301, 441, 442, - 313, 314, 637, 638, 299, 593, 624, 591, 636, 618, - 435, 375, 0, 0, 378, 280, 304, 319, 0, 609, - 499, 226, 463, 289, 250, 0, 0, 210, 245, 229, - 258, 273, 276, 323, 388, 397, 426, 431, 295, 270, - 243, 456, 240, 482, 514, 515, 516, 518, 392, 265, - 430, 393, 0, 373, 571, 572, 315, 0, 523, 0, - 0, 0, 0, 2390, 0, 0, 0, 0, 0, 0, - 413, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 363, 266, 0, 0, 427, 0, - 203, 0, 484, 251, 374, 371, 578, 281, 272, 268, - 249, 316, 382, 425, 513, 419, 0, 367, 0, 0, - 494, 398, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 322, 247, 324, - 202, 410, 495, 285, 0, 0, 0, 0, 0, 194, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 348, 357, 356, 337, - 338, 340, 342, 347, 354, 360, 0, 0, 602, 0, - 0, 0, 264, 320, 271, 263, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 399, 256, 0, 450, 0, 0, - 0, 620, 0, 0, 0, 0, 0, 0, 0, 362, - 0, 329, 197, 224, 0, 0, 409, 458, 470, 0, - 0, 0, 252, 0, 468, 423, 597, 232, 283, 455, - 429, 466, 437, 286, 0, 0, 467, 369, 580, 447, - 594, 621, 622, 262, 403, 607, 517, 615, 639, 225, - 259, 417, 502, 600, 491, 394, 576, 577, 328, 490, - 294, 201, 366, 627, 223, 476, 368, 241, 230, 582, - 604, 298, 288, 453, 634, 212, 512, 592, 238, 480, - 0, 0, 642, 246, 501, 214, 589, 500, 390, 325, - 326, 213, 0, 454, 267, 292, 0, 0, 257, 412, - 584, 585, 255, 643, 227, 614, 219, 0, 613, 405, - 579, 590, 391, 380, 218, 588, 389, 379, 333, 352, - 353, 279, 306, 444, 372, 445, 305, 307, 401, 400, - 402, 206, 601, 0, 207, 0, 496, 603, 644, 449, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 302, - 303, 312, 364, 416, 443, 439, 448, 0, 574, 595, - 608, 619, 625, 626, 628, 629, 630, 631, 632, 635, - 633, 404, 310, 492, 332, 370, 0, 0, 422, 469, - 239, 599, 493, 199, 0, 0, 0, 0, 253, 254, - 0, 570, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 659, 660, 661, 662, 640, - 503, 509, 504, 505, 506, 507, 508, 0, 510, 0, - 0, 0, 0, 0, 395, 0, 586, 587, 663, 381, - 483, 596, 334, 346, 349, 339, 358, 0, 359, 335, - 336, 341, 343, 344, 345, 350, 351, 355, 361, 248, - 209, 387, 396, 573, 311, 215, 216, 217, 519, 520, - 521, 522, 611, 612, 616, 204, 459, 460, 461, 462, - 291, 606, 308, 465, 464, 330, 331, 376, 446, 535, - 537, 548, 552, 554, 556, 562, 565, 536, 538, 549, - 553, 555, 557, 563, 566, 525, 527, 529, 531, 544, - 543, 540, 568, 569, 546, 551, 530, 542, 547, 560, - 567, 564, 524, 528, 532, 541, 559, 558, 539, 550, - 561, 545, 533, 526, 534, 0, 196, 220, 365, 0, - 451, 287, 641, 610, 481, 605, 205, 222, 0, 261, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 309, 317, 318, 321, 327, 377, 383, - 384, 385, 386, 406, 407, 408, 411, 414, 415, 418, - 420, 421, 424, 428, 432, 433, 434, 436, 438, 440, - 452, 457, 471, 472, 473, 474, 475, 478, 479, 485, - 486, 487, 488, 489, 497, 498, 511, 581, 583, 598, - 617, 623, 477, 300, 301, 441, 442, 313, 314, 637, - 638, 299, 593, 624, 591, 636, 618, 435, 375, 0, - 0, 378, 280, 304, 319, 0, 609, 499, 226, 463, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 323, 388, 397, 426, 431, 295, 270, 243, 456, 240, - 482, 514, 515, 516, 518, 392, 265, 430, 393, 0, - 373, 571, 572, 315, 0, 523, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 413, 0, 0, - 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 363, 266, 0, 0, 427, 0, 203, 0, 484, - 251, 374, 371, 578, 281, 272, 268, 249, 316, 382, - 425, 513, 419, 0, 367, 0, 0, 494, 398, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 322, 247, 324, 202, 410, 495, - 285, 0, 0, 0, 0, 1754, 713, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 348, 357, 356, 337, 338, 340, 342, - 347, 354, 360, 0, 0, 602, 0, 0, 0, 264, - 320, 271, 263, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 399, 256, 0, 450, 0, 0, 0, 620, 0, - 0, 0, 0, 0, 0, 0, 362, 0, 329, 197, - 224, 0, 0, 409, 458, 470, 0, 0, 0, 252, - 0, 468, 423, 597, 232, 283, 455, 429, 466, 437, - 286, 0, 0, 467, 369, 580, 447, 594, 621, 622, - 262, 403, 607, 517, 615, 639, 225, 259, 417, 502, - 600, 491, 394, 576, 577, 328, 490, 294, 201, 366, - 627, 223, 476, 368, 241, 230, 582, 604, 298, 288, - 453, 634, 212, 512, 592, 238, 480, 0, 0, 642, - 246, 501, 214, 589, 500, 390, 325, 326, 213, 0, - 454, 267, 292, 0, 0, 257, 412, 584, 585, 255, - 643, 227, 614, 219, 0, 613, 405, 579, 590, 391, - 380, 218, 588, 389, 379, 333, 352, 353, 279, 306, - 444, 372, 445, 305, 307, 401, 400, 402, 206, 601, - 0, 207, 0, 496, 603, 644, 449, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 302, 303, 312, 364, - 416, 443, 439, 448, 0, 574, 595, 608, 619, 625, - 626, 628, 629, 630, 631, 632, 635, 633, 404, 310, - 492, 332, 370, 0, 0, 422, 469, 239, 599, 493, - 199, 0, 0, 0, 0, 253, 254, 0, 570, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 659, 660, 661, 662, 640, 503, 509, 504, - 505, 506, 507, 508, 0, 510, 0, 0, 0, 0, - 0, 395, 0, 586, 587, 663, 381, 483, 596, 334, - 346, 349, 339, 358, 0, 359, 335, 336, 341, 343, - 344, 345, 350, 351, 355, 361, 248, 209, 387, 396, - 573, 311, 215, 216, 217, 519, 520, 521, 522, 611, - 612, 616, 204, 459, 460, 461, 462, 291, 606, 308, - 465, 464, 330, 331, 376, 446, 535, 537, 548, 552, - 554, 556, 562, 565, 536, 538, 549, 553, 555, 557, - 563, 566, 525, 527, 529, 531, 544, 543, 540, 568, - 569, 546, 551, 530, 542, 547, 560, 567, 564, 524, - 528, 532, 541, 559, 558, 539, 550, 561, 545, 533, - 526, 534, 0, 196, 220, 365, 0, 451, 287, 641, - 610, 481, 605, 205, 222, 0, 261, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 309, 317, 318, 321, 327, 377, 383, 384, 385, 386, - 406, 407, 408, 411, 414, 415, 418, 420, 421, 424, - 428, 432, 433, 434, 436, 438, 440, 452, 457, 471, - 472, 473, 474, 475, 478, 479, 485, 486, 487, 488, - 489, 497, 498, 511, 581, 583, 598, 617, 623, 477, - 300, 301, 441, 442, 313, 314, 637, 638, 299, 593, - 624, 591, 636, 618, 435, 375, 0, 0, 378, 280, - 304, 319, 0, 609, 499, 226, 463, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 323, 388, 397, - 426, 431, 295, 270, 243, 456, 240, 482, 514, 515, - 516, 518, 392, 265, 430, 393, 0, 373, 571, 572, - 315, 0, 523, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 413, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 363, 266, - 0, 0, 427, 0, 203, 0, 484, 251, 374, 371, - 578, 281, 272, 268, 249, 316, 382, 425, 513, 419, - 0, 367, 0, 0, 494, 398, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 322, 247, 324, 202, 410, 495, 285, 0, 0, - 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 348, 357, 356, 337, 338, 340, 342, 347, 354, 360, - 0, 0, 602, 0, 0, 0, 264, 320, 271, 263, - 575, 0, 0, 0, 0, 0, 0, 0, 0, 228, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 399, 256, - 0, 450, 0, 0, 0, 620, 0, 0, 0, 0, - 0, 0, 0, 362, 0, 329, 197, 224, 0, 0, - 409, 458, 470, 0, 0, 0, 252, 0, 468, 423, - 597, 232, 283, 455, 429, 466, 437, 286, 0, 0, - 467, 369, 580, 447, 594, 621, 622, 262, 403, 607, - 517, 615, 639, 225, 259, 417, 502, 600, 491, 394, - 576, 577, 328, 490, 294, 201, 366, 627, 223, 476, - 368, 241, 230, 582, 604, 298, 288, 453, 634, 212, - 512, 592, 238, 480, 0, 0, 642, 246, 501, 214, - 589, 500, 390, 325, 326, 213, 0, 454, 267, 292, - 0, 0, 257, 412, 584, 585, 255, 643, 227, 614, - 219, 0, 613, 405, 579, 590, 391, 380, 218, 588, - 389, 379, 333, 352, 353, 279, 306, 444, 372, 445, - 305, 307, 401, 400, 402, 206, 601, 0, 207, 0, - 496, 603, 644, 449, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 302, 303, 312, 364, 416, 443, 439, - 448, 0, 574, 595, 608, 619, 625, 626, 628, 629, - 630, 631, 632, 635, 633, 404, 310, 492, 332, 370, - 0, 0, 422, 469, 239, 599, 493, 199, 0, 0, - 0, 0, 253, 254, 0, 570, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, - 660, 661, 662, 640, 503, 509, 504, 505, 506, 507, - 508, 0, 510, 0, 0, 0, 0, 0, 395, 0, - 586, 587, 663, 381, 483, 596, 334, 346, 349, 339, - 358, 0, 359, 335, 336, 341, 343, 344, 345, 350, - 351, 355, 361, 248, 209, 387, 396, 573, 311, 215, - 216, 217, 519, 520, 521, 522, 611, 612, 616, 204, - 459, 460, 461, 462, 291, 606, 308, 465, 464, 330, - 331, 376, 446, 535, 537, 548, 552, 554, 556, 562, - 565, 536, 538, 549, 553, 555, 557, 563, 566, 525, - 527, 529, 531, 544, 543, 540, 568, 569, 546, 551, - 530, 542, 547, 560, 567, 564, 524, 528, 532, 541, - 559, 558, 539, 550, 561, 545, 533, 526, 534, 0, - 196, 220, 365, 2047, 451, 287, 641, 610, 481, 605, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 309, 317, 318, - 321, 327, 377, 383, 384, 385, 386, 406, 407, 408, - 411, 414, 415, 418, 420, 421, 424, 428, 432, 433, - 434, 436, 438, 440, 452, 457, 471, 472, 473, 474, - 475, 478, 479, 485, 486, 487, 488, 489, 497, 498, - 511, 581, 583, 598, 617, 623, 477, 300, 301, 441, - 442, 313, 314, 637, 638, 299, 593, 624, 591, 636, - 618, 435, 375, 0, 0, 378, 280, 304, 319, 0, - 609, 499, 226, 463, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 323, 388, 397, 426, 431, 295, - 270, 243, 456, 240, 482, 514, 515, 516, 518, 392, - 265, 430, 393, 0, 373, 571, 572, 315, 0, 523, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 413, 0, 0, 0, 0, 0, 0, 0, 0, - 269, 0, 0, 0, 0, 363, 266, 0, 0, 427, - 0, 203, 0, 484, 251, 374, 371, 578, 281, 272, - 268, 249, 316, 382, 425, 513, 419, 0, 367, 0, - 0, 494, 398, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 322, 247, - 324, 202, 410, 495, 285, 0, 0, 0, 0, 2038, - 713, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 348, 357, 356, - 337, 338, 340, 342, 347, 354, 360, 0, 0, 602, - 0, 0, 0, 264, 320, 271, 263, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 399, 256, 0, 450, 0, - 0, 0, 620, 0, 0, 0, 0, 0, 0, 0, - 362, 0, 329, 197, 224, 0, 0, 409, 458, 470, - 0, 0, 0, 252, 0, 468, 423, 597, 232, 283, - 455, 429, 466, 437, 286, 0, 0, 467, 369, 580, - 447, 594, 621, 622, 262, 403, 607, 517, 615, 639, - 225, 259, 417, 502, 600, 491, 394, 576, 577, 328, - 490, 294, 201, 366, 627, 223, 476, 368, 241, 230, - 582, 604, 298, 288, 453, 634, 212, 512, 592, 238, - 480, 0, 0, 642, 246, 501, 214, 589, 500, 390, - 325, 326, 213, 0, 454, 267, 292, 0, 0, 257, - 412, 584, 585, 255, 643, 227, 614, 219, 0, 613, - 405, 579, 590, 391, 380, 218, 588, 389, 379, 333, - 352, 353, 279, 306, 444, 372, 445, 305, 307, 401, - 400, 402, 206, 601, 0, 207, 0, 496, 603, 644, - 449, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 302, 303, 312, 364, 416, 443, 439, 448, 0, 574, - 595, 608, 619, 625, 626, 628, 629, 630, 631, 632, - 635, 633, 404, 310, 492, 332, 370, 0, 0, 422, - 469, 239, 599, 493, 199, 0, 0, 0, 0, 253, - 254, 0, 570, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, - 640, 503, 509, 504, 505, 506, 507, 508, 0, 510, - 0, 0, 0, 0, 0, 395, 0, 586, 587, 663, - 381, 483, 596, 334, 346, 349, 339, 358, 0, 359, - 335, 336, 341, 343, 344, 345, 350, 351, 355, 361, - 248, 209, 387, 396, 573, 311, 215, 216, 217, 519, - 520, 521, 522, 611, 612, 616, 204, 459, 460, 461, - 462, 291, 606, 308, 465, 464, 330, 331, 376, 446, - 535, 537, 548, 552, 554, 556, 562, 565, 536, 538, - 549, 553, 555, 557, 563, 566, 525, 527, 529, 531, - 544, 543, 540, 568, 569, 546, 551, 530, 542, 547, - 560, 567, 564, 524, 528, 532, 541, 559, 558, 539, - 550, 561, 545, 533, 526, 534, 0, 196, 220, 365, - 0, 451, 287, 641, 610, 481, 605, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 309, 317, 318, 321, 327, 377, - 383, 384, 385, 386, 406, 407, 408, 411, 414, 415, - 418, 420, 421, 424, 428, 432, 433, 434, 436, 438, - 440, 452, 457, 471, 472, 473, 474, 475, 478, 479, - 485, 486, 487, 488, 489, 497, 498, 511, 581, 583, - 598, 617, 623, 477, 300, 301, 441, 442, 313, 314, - 637, 638, 299, 593, 624, 591, 636, 618, 435, 375, - 0, 0, 378, 280, 304, 319, 0, 609, 499, 226, - 463, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 323, 388, 397, 426, 431, 295, 270, 243, 456, - 240, 482, 514, 515, 516, 518, 392, 265, 430, 393, - 0, 373, 571, 572, 315, 0, 523, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 413, 0, - 1900, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 363, 266, 0, 0, 427, 0, 203, 0, - 484, 251, 374, 371, 578, 281, 272, 268, 249, 316, - 382, 425, 513, 419, 0, 367, 0, 0, 494, 398, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 322, 247, 324, 202, 410, - 495, 285, 0, 0, 0, 0, 0, 713, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 348, 357, 356, 337, 338, 340, - 342, 347, 354, 360, 0, 0, 602, 0, 0, 0, - 264, 320, 271, 263, 575, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 399, 256, 0, 450, 0, 0, 0, 620, - 0, 0, 0, 0, 0, 0, 0, 362, 0, 329, - 197, 224, 0, 0, 409, 458, 470, 0, 0, 0, - 252, 0, 468, 423, 597, 232, 283, 455, 429, 466, - 437, 286, 0, 0, 467, 369, 580, 447, 594, 621, - 622, 262, 403, 607, 517, 615, 639, 225, 259, 417, - 502, 600, 491, 394, 576, 577, 328, 490, 294, 201, - 366, 627, 223, 476, 368, 241, 230, 582, 604, 298, - 288, 453, 634, 212, 512, 592, 238, 480, 0, 0, - 642, 246, 501, 214, 589, 500, 390, 325, 326, 213, - 0, 454, 267, 292, 0, 0, 257, 412, 584, 585, - 255, 643, 227, 614, 219, 0, 613, 405, 579, 590, - 391, 380, 218, 588, 389, 379, 333, 352, 353, 279, - 306, 444, 372, 445, 305, 307, 401, 400, 402, 206, - 601, 0, 207, 0, 496, 603, 644, 449, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 302, 303, 312, - 364, 416, 443, 439, 448, 0, 574, 595, 608, 619, - 625, 626, 628, 629, 630, 631, 632, 635, 633, 404, - 310, 492, 332, 370, 0, 0, 422, 469, 239, 599, - 493, 199, 0, 0, 0, 0, 253, 254, 0, 570, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 659, 660, 661, 662, 640, 503, 509, - 504, 505, 506, 507, 508, 0, 510, 0, 0, 0, - 0, 0, 395, 0, 586, 587, 663, 381, 483, 596, - 334, 346, 349, 339, 358, 0, 359, 335, 336, 341, - 343, 344, 345, 350, 351, 355, 361, 248, 209, 387, - 396, 573, 311, 215, 216, 217, 519, 520, 521, 522, - 611, 612, 616, 204, 459, 460, 461, 462, 291, 606, - 308, 465, 464, 330, 331, 376, 446, 535, 537, 548, - 552, 554, 556, 562, 565, 536, 538, 549, 553, 555, - 557, 563, 566, 525, 527, 529, 531, 544, 543, 540, - 568, 569, 546, 551, 530, 542, 547, 560, 567, 564, - 524, 528, 532, 541, 559, 558, 539, 550, 561, 545, - 533, 526, 534, 0, 196, 220, 365, 0, 451, 287, - 641, 610, 481, 605, 205, 222, 0, 261, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 309, 317, 318, 321, 327, 377, 383, 384, 385, - 386, 406, 407, 408, 411, 414, 415, 418, 420, 421, - 424, 428, 432, 433, 434, 436, 438, 440, 452, 457, - 471, 472, 473, 474, 475, 478, 479, 485, 486, 487, - 488, 489, 497, 498, 511, 581, 583, 598, 617, 623, - 477, 300, 301, 441, 442, 313, 314, 637, 638, 299, - 593, 624, 591, 636, 618, 435, 375, 0, 0, 378, - 280, 304, 319, 0, 609, 499, 226, 463, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 323, 388, - 397, 426, 431, 295, 270, 243, 456, 240, 482, 514, - 515, 516, 518, 392, 265, 430, 393, 0, 373, 571, - 572, 315, 0, 523, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 413, 0, 1898, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 363, - 266, 0, 0, 427, 0, 203, 0, 484, 251, 374, - 371, 578, 281, 272, 268, 249, 316, 382, 425, 513, - 419, 0, 367, 0, 0, 494, 398, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 322, 247, 324, 202, 410, 495, 285, 0, - 0, 0, 0, 0, 713, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 348, 357, 356, 337, 338, 340, 342, 347, 354, - 360, 0, 0, 602, 0, 0, 0, 264, 320, 271, - 263, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 296, 0, 399, - 256, 0, 450, 0, 0, 0, 620, 0, 0, 0, - 0, 0, 0, 0, 362, 0, 329, 197, 224, 0, - 0, 409, 458, 470, 0, 0, 0, 252, 0, 468, - 423, 597, 232, 283, 455, 429, 466, 437, 286, 0, - 0, 467, 369, 580, 447, 594, 621, 622, 262, 403, - 607, 517, 615, 639, 225, 259, 417, 502, 600, 491, - 394, 576, 577, 328, 490, 294, 201, 366, 627, 223, - 476, 368, 241, 230, 582, 604, 298, 288, 453, 634, - 212, 512, 592, 238, 480, 0, 0, 642, 246, 501, - 214, 589, 500, 390, 325, 326, 213, 0, 454, 267, - 292, 0, 0, 257, 412, 584, 585, 255, 643, 227, - 614, 219, 0, 613, 405, 579, 590, 391, 380, 218, - 588, 389, 379, 333, 352, 353, 279, 306, 444, 372, - 445, 305, 307, 401, 400, 402, 206, 601, 0, 207, - 0, 496, 603, 644, 449, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 302, 303, 312, 364, 416, 443, - 439, 448, 0, 574, 595, 608, 619, 625, 626, 628, - 629, 630, 631, 632, 635, 633, 404, 310, 492, 332, - 370, 0, 0, 422, 469, 239, 599, 493, 199, 0, - 0, 0, 0, 253, 254, 0, 570, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 659, 660, 661, 662, 640, 503, 509, 504, 505, 506, - 507, 508, 0, 510, 0, 0, 0, 0, 0, 395, - 0, 586, 587, 663, 381, 483, 596, 334, 346, 349, - 339, 358, 0, 359, 335, 336, 341, 343, 344, 345, - 350, 351, 355, 361, 248, 209, 387, 396, 573, 311, - 215, 216, 217, 519, 520, 521, 522, 611, 612, 616, - 204, 459, 460, 461, 462, 291, 606, 308, 465, 464, - 330, 331, 376, 446, 535, 537, 548, 552, 554, 556, - 562, 565, 536, 538, 549, 553, 555, 557, 563, 566, - 525, 527, 529, 531, 544, 543, 540, 568, 569, 546, - 551, 530, 542, 547, 560, 567, 564, 524, 528, 532, - 541, 559, 558, 539, 550, 561, 545, 533, 526, 534, - 0, 196, 220, 365, 0, 451, 287, 641, 610, 481, - 605, 205, 222, 0, 261, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 309, 317, - 318, 321, 327, 377, 383, 384, 385, 386, 406, 407, - 408, 411, 414, 415, 418, 420, 421, 424, 428, 432, - 433, 434, 436, 438, 440, 452, 457, 471, 472, 473, - 474, 475, 478, 479, 485, 486, 487, 488, 489, 497, - 498, 511, 581, 583, 598, 617, 623, 477, 300, 301, - 441, 442, 313, 314, 637, 638, 299, 593, 624, 591, - 636, 618, 435, 375, 0, 0, 378, 280, 304, 319, - 0, 609, 499, 226, 463, 289, 250, 0, 0, 210, - 245, 229, 258, 273, 276, 323, 388, 397, 426, 431, - 295, 270, 243, 456, 240, 482, 514, 515, 516, 518, - 392, 265, 430, 393, 0, 373, 571, 572, 315, 0, - 523, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 413, 0, 1896, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 363, 266, 0, 0, - 427, 0, 203, 0, 484, 251, 374, 371, 578, 281, - 272, 268, 249, 316, 382, 425, 513, 419, 0, 367, - 0, 0, 494, 398, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 322, - 247, 324, 202, 410, 495, 285, 0, 0, 0, 0, - 0, 713, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 348, 357, - 356, 337, 338, 340, 342, 347, 354, 360, 0, 0, - 602, 0, 0, 0, 264, 320, 271, 263, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 399, 256, 0, 450, - 0, 0, 0, 620, 0, 0, 0, 0, 0, 0, - 0, 362, 0, 329, 197, 224, 0, 0, 409, 458, - 470, 0, 0, 0, 252, 0, 468, 423, 597, 232, - 283, 455, 429, 466, 437, 286, 0, 0, 467, 369, - 580, 447, 594, 621, 622, 262, 403, 607, 517, 615, - 639, 225, 259, 417, 502, 600, 491, 394, 576, 577, - 328, 490, 294, 201, 366, 627, 223, 476, 368, 241, - 230, 582, 604, 298, 288, 453, 634, 212, 512, 592, - 238, 480, 0, 0, 642, 246, 501, 214, 589, 500, - 390, 325, 326, 213, 0, 454, 267, 292, 0, 0, - 257, 412, 584, 585, 255, 643, 227, 614, 219, 0, - 613, 405, 579, 590, 391, 380, 218, 588, 389, 379, - 333, 352, 353, 279, 306, 444, 372, 445, 305, 307, - 401, 400, 402, 206, 601, 0, 207, 0, 496, 603, - 644, 449, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 302, 303, 312, 364, 416, 443, 439, 448, 0, - 574, 595, 608, 619, 625, 626, 628, 629, 630, 631, - 632, 635, 633, 404, 310, 492, 332, 370, 0, 0, - 422, 469, 239, 599, 493, 199, 0, 0, 0, 0, - 253, 254, 0, 570, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, - 662, 640, 503, 509, 504, 505, 506, 507, 508, 0, - 510, 0, 0, 0, 0, 0, 395, 0, 586, 587, - 663, 381, 483, 596, 334, 346, 349, 339, 358, 0, - 359, 335, 336, 341, 343, 344, 345, 350, 351, 355, - 361, 248, 209, 387, 396, 573, 311, 215, 216, 217, - 519, 520, 521, 522, 611, 612, 616, 204, 459, 460, - 461, 462, 291, 606, 308, 465, 464, 330, 331, 376, - 446, 535, 537, 548, 552, 554, 556, 562, 565, 536, - 538, 549, 553, 555, 557, 563, 566, 525, 527, 529, - 531, 544, 543, 540, 568, 569, 546, 551, 530, 542, - 547, 560, 567, 564, 524, 528, 532, 541, 559, 558, - 539, 550, 561, 545, 533, 526, 534, 0, 196, 220, - 365, 0, 451, 287, 641, 610, 481, 605, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 309, 317, 318, 321, 327, - 377, 383, 384, 385, 386, 406, 407, 408, 411, 414, - 415, 418, 420, 421, 424, 428, 432, 433, 434, 436, - 438, 440, 452, 457, 471, 472, 473, 474, 475, 478, - 479, 485, 486, 487, 488, 489, 497, 498, 511, 581, - 583, 598, 617, 623, 477, 300, 301, 441, 442, 313, - 314, 637, 638, 299, 593, 624, 591, 636, 618, 435, - 375, 0, 0, 378, 280, 304, 319, 0, 609, 499, - 226, 463, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 323, 388, 397, 426, 431, 295, 270, 243, - 456, 240, 482, 514, 515, 516, 518, 392, 265, 430, - 393, 0, 373, 571, 572, 315, 0, 523, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 413, - 0, 1894, 0, 0, 0, 0, 0, 0, 269, 0, - 0, 0, 0, 363, 266, 0, 0, 427, 0, 203, - 0, 484, 251, 374, 371, 578, 281, 272, 268, 249, - 316, 382, 425, 513, 419, 0, 367, 0, 0, 494, - 398, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 322, 247, 324, 202, - 410, 495, 285, 0, 0, 0, 0, 0, 713, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 348, 357, 356, 337, 338, - 340, 342, 347, 354, 360, 0, 0, 602, 0, 0, - 0, 264, 320, 271, 263, 575, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 399, 256, 0, 450, 0, 0, 0, - 620, 0, 0, 0, 0, 0, 0, 0, 362, 0, - 329, 197, 224, 0, 0, 409, 458, 470, 0, 0, - 0, 252, 0, 468, 423, 597, 232, 283, 455, 429, - 466, 437, 286, 0, 0, 467, 369, 580, 447, 594, - 621, 622, 262, 403, 607, 517, 615, 639, 225, 259, - 417, 502, 600, 491, 394, 576, 577, 328, 490, 294, - 201, 366, 627, 223, 476, 368, 241, 230, 582, 604, - 298, 288, 453, 634, 212, 512, 592, 238, 480, 0, - 0, 642, 246, 501, 214, 589, 500, 390, 325, 326, - 213, 0, 454, 267, 292, 0, 0, 257, 412, 584, - 585, 255, 643, 227, 614, 219, 0, 613, 405, 579, - 590, 391, 380, 218, 588, 389, 379, 333, 352, 353, - 279, 306, 444, 372, 445, 305, 307, 401, 400, 402, - 206, 601, 0, 207, 0, 496, 603, 644, 449, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 302, 303, - 312, 364, 416, 443, 439, 448, 0, 574, 595, 608, - 619, 625, 626, 628, 629, 630, 631, 632, 635, 633, - 404, 310, 492, 332, 370, 0, 0, 422, 469, 239, - 599, 493, 199, 0, 0, 0, 0, 253, 254, 0, - 570, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 659, 660, 661, 662, 640, 503, - 509, 504, 505, 506, 507, 508, 0, 510, 0, 0, - 0, 0, 0, 395, 0, 586, 587, 663, 381, 483, - 596, 334, 346, 349, 339, 358, 0, 359, 335, 336, - 341, 343, 344, 345, 350, 351, 355, 361, 248, 209, - 387, 396, 573, 311, 215, 216, 217, 519, 520, 521, - 522, 611, 612, 616, 204, 459, 460, 461, 462, 291, - 606, 308, 465, 464, 330, 331, 376, 446, 535, 537, - 548, 552, 554, 556, 562, 565, 536, 538, 549, 553, - 555, 557, 563, 566, 525, 527, 529, 531, 544, 543, - 540, 568, 569, 546, 551, 530, 542, 547, 560, 567, - 564, 524, 528, 532, 541, 559, 558, 539, 550, 561, - 545, 533, 526, 534, 0, 196, 220, 365, 0, 451, - 287, 641, 610, 481, 605, 205, 222, 0, 261, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 309, 317, 318, 321, 327, 377, 383, 384, - 385, 386, 406, 407, 408, 411, 414, 415, 418, 420, - 421, 424, 428, 432, 433, 434, 436, 438, 440, 452, - 457, 471, 472, 473, 474, 475, 478, 479, 485, 486, - 487, 488, 489, 497, 498, 511, 581, 583, 598, 617, - 623, 477, 300, 301, 441, 442, 313, 314, 637, 638, - 299, 593, 624, 591, 636, 618, 435, 375, 0, 0, - 378, 280, 304, 319, 0, 609, 499, 226, 463, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 323, - 388, 397, 426, 431, 295, 270, 243, 456, 240, 482, - 514, 515, 516, 518, 392, 265, 430, 393, 0, 373, - 571, 572, 315, 0, 523, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 413, 0, 1892, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 363, 266, 0, 0, 427, 0, 203, 0, 484, 251, - 374, 371, 578, 281, 272, 268, 249, 316, 382, 425, - 513, 419, 0, 367, 0, 0, 494, 398, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 322, 247, 324, 202, 410, 495, 285, - 0, 0, 0, 0, 0, 713, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 348, 357, 356, 337, 338, 340, 342, 347, - 354, 360, 0, 0, 602, 0, 0, 0, 264, 320, - 271, 263, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 399, 256, 0, 450, 0, 0, 0, 620, 0, 0, - 0, 0, 0, 0, 0, 362, 0, 329, 197, 224, - 0, 0, 409, 458, 470, 0, 0, 0, 252, 0, - 468, 423, 597, 232, 283, 455, 429, 466, 437, 286, - 0, 0, 467, 369, 580, 447, 594, 621, 622, 262, - 403, 607, 517, 615, 639, 225, 259, 417, 502, 600, - 491, 394, 576, 577, 328, 490, 294, 201, 366, 627, - 223, 476, 368, 241, 230, 582, 604, 298, 288, 453, - 634, 212, 512, 592, 238, 480, 0, 0, 642, 246, - 501, 214, 589, 500, 390, 325, 326, 213, 0, 454, - 267, 292, 0, 0, 257, 412, 584, 585, 255, 643, - 227, 614, 219, 0, 613, 405, 579, 590, 391, 380, - 218, 588, 389, 379, 333, 352, 353, 279, 306, 444, - 372, 445, 305, 307, 401, 400, 402, 206, 601, 0, - 207, 0, 496, 603, 644, 449, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 302, 303, 312, 364, 416, - 443, 439, 448, 0, 574, 595, 608, 619, 625, 626, - 628, 629, 630, 631, 632, 635, 633, 404, 310, 492, - 332, 370, 0, 0, 422, 469, 239, 599, 493, 199, - 0, 0, 0, 0, 253, 254, 0, 570, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 659, 660, 661, 662, 640, 503, 509, 504, 505, - 506, 507, 508, 0, 510, 0, 0, 0, 0, 0, - 395, 0, 586, 587, 663, 381, 483, 596, 334, 346, - 349, 339, 358, 0, 359, 335, 336, 341, 343, 344, - 345, 350, 351, 355, 361, 248, 209, 387, 396, 573, - 311, 215, 216, 217, 519, 520, 521, 522, 611, 612, - 616, 204, 459, 460, 461, 462, 291, 606, 308, 465, - 464, 330, 331, 376, 446, 535, 537, 548, 552, 554, - 556, 562, 565, 536, 538, 549, 553, 555, 557, 563, - 566, 525, 527, 529, 531, 544, 543, 540, 568, 569, - 546, 551, 530, 542, 547, 560, 567, 564, 524, 528, - 532, 541, 559, 558, 539, 550, 561, 545, 533, 526, - 534, 0, 196, 220, 365, 0, 451, 287, 641, 610, - 481, 605, 205, 222, 0, 261, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 309, - 317, 318, 321, 327, 377, 383, 384, 385, 386, 406, - 407, 408, 411, 414, 415, 418, 420, 421, 424, 428, - 432, 433, 434, 436, 438, 440, 452, 457, 471, 472, - 473, 474, 475, 478, 479, 485, 486, 487, 488, 489, - 497, 498, 511, 581, 583, 598, 617, 623, 477, 300, - 301, 441, 442, 313, 314, 637, 638, 299, 593, 624, - 591, 636, 618, 435, 375, 0, 0, 378, 280, 304, - 319, 0, 609, 499, 226, 463, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 323, 388, 397, 426, - 431, 295, 270, 243, 456, 240, 482, 514, 515, 516, - 518, 392, 265, 430, 393, 0, 373, 571, 572, 315, - 0, 523, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 413, 0, 1888, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 363, 266, 0, - 0, 427, 0, 203, 0, 484, 251, 374, 371, 578, - 281, 272, 268, 249, 316, 382, 425, 513, 419, 0, - 367, 0, 0, 494, 398, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 322, 247, 324, 202, 410, 495, 285, 0, 0, 0, - 0, 0, 713, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 348, - 357, 356, 337, 338, 340, 342, 347, 354, 360, 0, - 0, 602, 0, 0, 0, 264, 320, 271, 263, 575, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 399, 256, 0, - 450, 0, 0, 0, 620, 0, 0, 0, 0, 0, - 0, 0, 362, 0, 329, 197, 224, 0, 0, 409, - 458, 470, 0, 0, 0, 252, 0, 468, 423, 597, - 232, 283, 455, 429, 466, 437, 286, 0, 0, 467, - 369, 580, 447, 594, 621, 622, 262, 403, 607, 517, - 615, 639, 225, 259, 417, 502, 600, 491, 394, 576, - 577, 328, 490, 294, 201, 366, 627, 223, 476, 368, - 241, 230, 582, 604, 298, 288, 453, 634, 212, 512, - 592, 238, 480, 0, 0, 642, 246, 501, 214, 589, - 500, 390, 325, 326, 213, 0, 454, 267, 292, 0, - 0, 257, 412, 584, 585, 255, 643, 227, 614, 219, - 0, 613, 405, 579, 590, 391, 380, 218, 588, 389, - 379, 333, 352, 353, 279, 306, 444, 372, 445, 305, - 307, 401, 400, 402, 206, 601, 0, 207, 0, 496, - 603, 644, 449, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 302, 303, 312, 364, 416, 443, 439, 448, - 0, 574, 595, 608, 619, 625, 626, 628, 629, 630, - 631, 632, 635, 633, 404, 310, 492, 332, 370, 0, - 0, 422, 469, 239, 599, 493, 199, 0, 0, 0, - 0, 253, 254, 0, 570, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, - 661, 662, 640, 503, 509, 504, 505, 506, 507, 508, - 0, 510, 0, 0, 0, 0, 0, 395, 0, 586, - 587, 663, 381, 483, 596, 334, 346, 349, 339, 358, - 0, 359, 335, 336, 341, 343, 344, 345, 350, 351, - 355, 361, 248, 209, 387, 396, 573, 311, 215, 216, - 217, 519, 520, 521, 522, 611, 612, 616, 204, 459, - 460, 461, 462, 291, 606, 308, 465, 464, 330, 331, - 376, 446, 535, 537, 548, 552, 554, 556, 562, 565, - 536, 538, 549, 553, 555, 557, 563, 566, 525, 527, - 529, 531, 544, 543, 540, 568, 569, 546, 551, 530, - 542, 547, 560, 567, 564, 524, 528, 532, 541, 559, - 558, 539, 550, 561, 545, 533, 526, 534, 0, 196, - 220, 365, 0, 451, 287, 641, 610, 481, 605, 205, - 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 309, 317, 318, 321, - 327, 377, 383, 384, 385, 386, 406, 407, 408, 411, - 414, 415, 418, 420, 421, 424, 428, 432, 433, 434, - 436, 438, 440, 452, 457, 471, 472, 473, 474, 475, - 478, 479, 485, 486, 487, 488, 489, 497, 498, 511, - 581, 583, 598, 617, 623, 477, 300, 301, 441, 442, - 313, 314, 637, 638, 299, 593, 624, 591, 636, 618, - 435, 375, 0, 0, 378, 280, 304, 319, 0, 609, - 499, 226, 463, 289, 250, 0, 0, 210, 245, 229, - 258, 273, 276, 323, 388, 397, 426, 431, 295, 270, - 243, 456, 240, 482, 514, 515, 516, 518, 392, 265, - 430, 393, 0, 373, 571, 572, 315, 0, 523, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 413, 0, 1886, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 363, 266, 0, 0, 427, 0, - 203, 0, 484, 251, 374, 371, 578, 281, 272, 268, - 249, 316, 382, 425, 513, 419, 0, 367, 0, 0, - 494, 398, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 322, 247, 324, - 202, 410, 495, 285, 0, 0, 0, 0, 0, 713, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 348, 357, 356, 337, - 338, 340, 342, 347, 354, 360, 0, 0, 602, 0, - 0, 0, 264, 320, 271, 263, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 399, 256, 0, 450, 0, 0, - 0, 620, 0, 0, 0, 0, 0, 0, 0, 362, - 0, 329, 197, 224, 0, 0, 409, 458, 470, 0, - 0, 0, 252, 0, 468, 423, 597, 232, 283, 455, - 429, 466, 437, 286, 0, 0, 467, 369, 580, 447, - 594, 621, 622, 262, 403, 607, 517, 615, 639, 225, - 259, 417, 502, 600, 491, 394, 576, 577, 328, 490, - 294, 201, 366, 627, 223, 476, 368, 241, 230, 582, - 604, 298, 288, 453, 634, 212, 512, 592, 238, 480, - 0, 0, 642, 246, 501, 214, 589, 500, 390, 325, - 326, 213, 0, 454, 267, 292, 0, 0, 257, 412, - 584, 585, 255, 643, 227, 614, 219, 0, 613, 405, - 579, 590, 391, 380, 218, 588, 389, 379, 333, 352, - 353, 279, 306, 444, 372, 445, 305, 307, 401, 400, - 402, 206, 601, 0, 207, 0, 496, 603, 644, 449, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 302, - 303, 312, 364, 416, 443, 439, 448, 0, 574, 595, - 608, 619, 625, 626, 628, 629, 630, 631, 632, 635, - 633, 404, 310, 492, 332, 370, 0, 0, 422, 469, - 239, 599, 493, 199, 0, 0, 0, 0, 253, 254, - 0, 570, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 659, 660, 661, 662, 640, - 503, 509, 504, 505, 506, 507, 508, 0, 510, 0, - 0, 0, 0, 0, 395, 0, 586, 587, 663, 381, - 483, 596, 334, 346, 349, 339, 358, 0, 359, 335, - 336, 341, 343, 344, 345, 350, 351, 355, 361, 248, - 209, 387, 396, 573, 311, 215, 216, 217, 519, 520, - 521, 522, 611, 612, 616, 204, 459, 460, 461, 462, - 291, 606, 308, 465, 464, 330, 331, 376, 446, 535, - 537, 548, 552, 554, 556, 562, 565, 536, 538, 549, - 553, 555, 557, 563, 566, 525, 527, 529, 531, 544, - 543, 540, 568, 569, 546, 551, 530, 542, 547, 560, - 567, 564, 524, 528, 532, 541, 559, 558, 539, 550, - 561, 545, 533, 526, 534, 0, 196, 220, 365, 0, - 451, 287, 641, 610, 481, 605, 205, 222, 0, 261, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 309, 317, 318, 321, 327, 377, 383, - 384, 385, 386, 406, 407, 408, 411, 414, 415, 418, - 420, 421, 424, 428, 432, 433, 434, 436, 438, 440, - 452, 457, 471, 472, 473, 474, 475, 478, 479, 485, - 486, 487, 488, 489, 497, 498, 511, 581, 583, 598, - 617, 623, 477, 300, 301, 441, 442, 313, 314, 637, - 638, 299, 593, 624, 591, 636, 618, 435, 375, 0, - 0, 378, 280, 304, 319, 0, 609, 499, 226, 463, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 323, 388, 397, 426, 431, 295, 270, 243, 456, 240, - 482, 514, 515, 516, 518, 392, 265, 430, 393, 0, - 373, 571, 572, 315, 0, 523, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 413, 0, 1884, - 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 363, 266, 0, 0, 427, 0, 203, 0, 484, - 251, 374, 371, 578, 281, 272, 268, 249, 316, 382, - 425, 513, 419, 0, 367, 0, 0, 494, 398, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 322, 247, 324, 202, 410, 495, - 285, 0, 0, 0, 0, 0, 713, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 348, 357, 356, 337, 338, 340, 342, - 347, 354, 360, 0, 0, 602, 0, 0, 0, 264, - 320, 271, 263, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 399, 256, 0, 450, 0, 0, 0, 620, 0, - 0, 0, 0, 0, 0, 0, 362, 0, 329, 197, - 224, 0, 0, 409, 458, 470, 0, 0, 0, 252, - 0, 468, 423, 597, 232, 283, 455, 429, 466, 437, - 286, 0, 0, 467, 369, 580, 447, 594, 621, 622, - 262, 403, 607, 517, 615, 639, 225, 259, 417, 502, - 600, 491, 394, 576, 577, 328, 490, 294, 201, 366, - 627, 223, 476, 368, 241, 230, 582, 604, 298, 288, - 453, 634, 212, 512, 592, 238, 480, 0, 0, 642, - 246, 501, 214, 589, 500, 390, 325, 326, 213, 0, - 454, 267, 292, 0, 0, 257, 412, 584, 585, 255, - 643, 227, 614, 219, 0, 613, 405, 579, 590, 391, - 380, 218, 588, 389, 379, 333, 352, 353, 279, 306, - 444, 372, 445, 305, 307, 401, 400, 402, 206, 601, - 0, 207, 0, 496, 603, 644, 449, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 302, 303, 312, 364, - 416, 443, 439, 448, 0, 574, 595, 608, 619, 625, - 626, 628, 629, 630, 631, 632, 635, 633, 404, 310, - 492, 332, 370, 0, 0, 422, 469, 239, 599, 493, - 199, 0, 0, 0, 0, 253, 254, 0, 570, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 659, 660, 661, 662, 640, 503, 509, 504, - 505, 506, 507, 508, 0, 510, 0, 0, 0, 0, - 0, 395, 0, 586, 587, 663, 381, 483, 596, 334, - 346, 349, 339, 358, 0, 359, 335, 336, 341, 343, - 344, 345, 350, 351, 355, 361, 248, 209, 387, 396, - 573, 311, 215, 216, 217, 519, 520, 521, 522, 611, - 612, 616, 204, 459, 460, 461, 462, 291, 606, 308, - 465, 464, 330, 331, 376, 446, 535, 537, 548, 552, - 554, 556, 562, 565, 536, 538, 549, 553, 555, 557, - 563, 566, 525, 527, 529, 531, 544, 543, 540, 568, - 569, 546, 551, 530, 542, 547, 560, 567, 564, 524, - 528, 532, 541, 559, 558, 539, 550, 561, 545, 533, - 526, 534, 0, 196, 220, 365, 0, 451, 287, 641, - 610, 481, 605, 205, 222, 0, 261, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 309, 317, 318, 321, 327, 377, 383, 384, 385, 386, - 406, 407, 408, 411, 414, 415, 418, 420, 421, 424, - 428, 432, 433, 434, 436, 438, 440, 452, 457, 471, - 472, 473, 474, 475, 478, 479, 485, 486, 487, 488, - 489, 497, 498, 511, 581, 583, 598, 617, 623, 477, - 300, 301, 441, 442, 313, 314, 637, 638, 299, 593, - 624, 591, 636, 618, 435, 375, 0, 0, 378, 280, - 304, 319, 0, 609, 499, 226, 463, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 323, 388, 397, - 426, 431, 295, 270, 243, 456, 240, 482, 514, 515, - 516, 518, 392, 265, 430, 393, 0, 373, 571, 572, - 315, 0, 523, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 413, 0, 0, 0, 0, 0, - 0, 0, 0, 269, 0, 0, 0, 0, 363, 266, - 0, 0, 427, 0, 203, 0, 484, 251, 374, 371, - 578, 281, 272, 268, 249, 316, 382, 425, 513, 419, - 0, 367, 0, 0, 494, 398, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 322, 247, 324, 202, 410, 495, 285, 0, 1859, - 0, 0, 0, 713, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 244, 0, 0, 0, - 348, 357, 356, 337, 338, 340, 342, 347, 354, 360, - 0, 0, 602, 0, 0, 0, 264, 320, 271, 263, - 575, 0, 0, 0, 0, 0, 0, 0, 0, 228, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 296, 0, 399, 256, - 0, 450, 0, 0, 0, 620, 0, 0, 0, 0, - 0, 0, 0, 362, 0, 329, 197, 224, 0, 0, - 409, 458, 470, 0, 0, 0, 252, 0, 468, 423, - 597, 232, 283, 455, 429, 466, 437, 286, 0, 0, - 467, 369, 580, 447, 594, 621, 622, 262, 403, 607, - 517, 615, 639, 225, 259, 417, 502, 600, 491, 394, - 576, 577, 328, 490, 294, 201, 366, 627, 223, 476, - 368, 241, 230, 582, 604, 298, 288, 453, 634, 212, - 512, 592, 238, 480, 0, 0, 642, 246, 501, 214, - 589, 500, 390, 325, 326, 213, 0, 454, 267, 292, - 0, 0, 257, 412, 584, 585, 255, 643, 227, 614, - 219, 0, 613, 405, 579, 590, 391, 380, 218, 588, - 389, 379, 333, 352, 353, 279, 306, 444, 372, 445, - 305, 307, 401, 400, 402, 206, 601, 0, 207, 0, - 496, 603, 644, 449, 211, 233, 234, 236, 0, 278, - 282, 290, 293, 302, 303, 312, 364, 416, 443, 439, - 448, 0, 574, 595, 608, 619, 625, 626, 628, 629, - 630, 631, 632, 635, 633, 404, 310, 492, 332, 370, - 0, 0, 422, 469, 239, 599, 493, 199, 0, 0, - 0, 0, 253, 254, 0, 570, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 645, 646, 647, 648, 649, - 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, - 660, 661, 662, 640, 503, 509, 504, 505, 506, 507, - 508, 0, 510, 0, 0, 0, 0, 0, 395, 0, - 586, 587, 663, 381, 483, 596, 334, 346, 349, 339, - 358, 0, 359, 335, 336, 341, 343, 344, 345, 350, - 351, 355, 361, 248, 209, 387, 396, 573, 311, 215, - 216, 217, 519, 520, 521, 522, 611, 612, 616, 204, - 459, 460, 461, 462, 291, 606, 308, 465, 464, 330, - 331, 376, 446, 535, 537, 548, 552, 554, 556, 562, - 565, 536, 538, 549, 553, 555, 557, 563, 566, 525, - 527, 529, 531, 544, 543, 540, 568, 569, 546, 551, - 530, 542, 547, 560, 567, 564, 524, 528, 532, 541, - 559, 558, 539, 550, 561, 545, 533, 526, 534, 0, - 196, 220, 365, 0, 451, 287, 641, 610, 481, 605, - 205, 222, 0, 261, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 200, 208, 221, 231, - 235, 242, 260, 275, 277, 284, 297, 309, 317, 318, - 321, 327, 377, 383, 384, 385, 386, 406, 407, 408, - 411, 414, 415, 418, 420, 421, 424, 428, 432, 433, - 434, 436, 438, 440, 452, 457, 471, 472, 473, 474, - 475, 478, 479, 485, 486, 487, 488, 489, 497, 498, - 511, 581, 583, 598, 617, 623, 477, 300, 301, 441, - 442, 313, 314, 637, 638, 299, 593, 624, 591, 636, - 618, 435, 375, 0, 0, 378, 280, 304, 319, 0, - 609, 499, 226, 463, 289, 250, 0, 0, 210, 245, - 229, 258, 273, 276, 323, 388, 397, 426, 431, 295, - 270, 243, 456, 240, 482, 514, 515, 516, 518, 392, - 265, 430, 393, 0, 373, 571, 572, 315, 0, 523, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 413, 0, 0, 0, 0, 0, 0, 0, 1758, - 269, 0, 0, 0, 0, 363, 266, 0, 0, 427, - 0, 203, 0, 484, 251, 374, 371, 578, 281, 272, - 268, 249, 316, 382, 425, 513, 419, 0, 367, 0, - 0, 494, 398, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 322, 247, - 324, 202, 410, 495, 285, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 94, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 2395, 0, 0, + 2394, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 1753, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 1755, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 1757, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 1461, 0, 1462, 1463, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 86, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 1730, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 94, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 244, 0, 0, 0, 348, 357, 356, - 337, 338, 340, 342, 347, 354, 360, 0, 0, 602, - 0, 0, 0, 264, 320, 271, 263, 575, 0, 0, - 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 0, 399, 256, 0, 450, 0, - 0, 0, 620, 0, 0, 0, 0, 0, 0, 0, - 362, 0, 329, 197, 224, 0, 0, 409, 458, 470, - 0, 0, 0, 252, 0, 468, 423, 597, 232, 283, - 455, 429, 466, 437, 286, 0, 0, 467, 369, 580, - 447, 594, 621, 622, 262, 403, 607, 517, 615, 639, - 225, 259, 417, 502, 600, 491, 394, 576, 577, 328, - 490, 294, 201, 366, 627, 223, 476, 368, 241, 230, - 582, 604, 298, 288, 453, 634, 212, 512, 592, 238, - 480, 0, 0, 642, 246, 501, 214, 589, 500, 390, - 325, 326, 213, 0, 454, 267, 292, 0, 0, 257, - 412, 584, 585, 255, 643, 227, 614, 219, 0, 613, - 405, 579, 590, 391, 380, 218, 588, 389, 379, 333, - 352, 353, 279, 306, 444, 372, 445, 305, 307, 401, - 400, 402, 206, 601, 0, 207, 0, 496, 603, 644, - 449, 211, 233, 234, 236, 0, 278, 282, 290, 293, - 302, 303, 312, 364, 416, 443, 439, 448, 0, 574, - 595, 608, 619, 625, 626, 628, 629, 630, 631, 632, - 635, 633, 404, 310, 492, 332, 370, 0, 0, 422, - 469, 239, 599, 493, 199, 0, 0, 0, 0, 253, - 254, 0, 570, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 645, 646, 647, 648, 649, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, - 640, 503, 509, 504, 505, 506, 507, 508, 0, 510, - 0, 0, 0, 0, 0, 395, 0, 586, 587, 663, - 381, 483, 596, 334, 346, 349, 339, 358, 0, 359, - 335, 336, 341, 343, 344, 345, 350, 351, 355, 361, - 248, 209, 387, 396, 573, 311, 215, 216, 217, 519, - 520, 521, 522, 611, 612, 616, 204, 459, 460, 461, - 462, 291, 606, 308, 465, 464, 330, 331, 376, 446, - 535, 537, 548, 552, 554, 556, 562, 565, 536, 538, - 549, 553, 555, 557, 563, 566, 525, 527, 529, 531, - 544, 543, 540, 568, 569, 546, 551, 530, 542, 547, - 560, 567, 564, 524, 528, 532, 541, 559, 558, 539, - 550, 561, 545, 533, 526, 534, 0, 196, 220, 365, - 0, 451, 287, 641, 610, 481, 605, 205, 222, 0, - 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 198, 200, 208, 221, 231, 235, 242, 260, - 275, 277, 284, 297, 309, 317, 318, 321, 327, 377, - 383, 384, 385, 386, 406, 407, 408, 411, 414, 415, - 418, 420, 421, 424, 428, 432, 433, 434, 436, 438, - 440, 452, 457, 471, 472, 473, 474, 475, 478, 479, - 485, 486, 487, 488, 489, 497, 498, 511, 581, 583, - 598, 617, 623, 477, 300, 301, 441, 442, 313, 314, - 637, 638, 299, 593, 624, 591, 636, 618, 435, 375, - 0, 0, 378, 280, 304, 319, 0, 609, 499, 226, - 463, 289, 250, 0, 0, 210, 245, 229, 258, 273, - 276, 323, 388, 397, 426, 431, 295, 270, 243, 456, - 240, 482, 514, 515, 516, 518, 392, 265, 430, 393, - 0, 373, 571, 572, 315, 0, 523, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 413, 0, - 0, 0, 0, 0, 0, 0, 0, 269, 0, 0, - 0, 0, 363, 266, 0, 0, 427, 0, 203, 0, - 484, 251, 374, 371, 578, 281, 272, 268, 249, 316, - 382, 425, 513, 419, 0, 367, 0, 0, 494, 398, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 322, 247, 324, 202, 410, - 495, 285, 0, 95, 0, 0, 0, 946, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 244, 0, 0, 0, 348, 357, 356, 337, 338, 340, - 342, 347, 354, 360, 0, 0, 602, 0, 0, 0, - 264, 320, 271, 263, 575, 0, 0, 0, 0, 0, - 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 296, 0, 399, 256, 0, 450, 0, 0, 0, 620, - 0, 0, 0, 0, 0, 0, 0, 362, 0, 329, - 197, 224, 0, 0, 409, 458, 470, 0, 0, 0, - 252, 0, 468, 423, 597, 232, 283, 455, 429, 466, - 437, 286, 0, 0, 467, 369, 580, 447, 594, 621, - 622, 262, 403, 607, 517, 615, 639, 225, 259, 417, - 502, 600, 491, 394, 576, 577, 328, 490, 294, 201, - 366, 627, 223, 476, 368, 241, 230, 582, 604, 298, - 288, 453, 634, 212, 512, 592, 238, 480, 0, 0, - 642, 246, 501, 214, 589, 500, 390, 325, 326, 213, - 0, 454, 267, 292, 0, 0, 257, 412, 584, 585, - 255, 643, 227, 614, 219, 0, 613, 405, 579, 590, - 391, 380, 218, 588, 389, 379, 333, 352, 353, 279, - 306, 444, 372, 445, 305, 307, 401, 400, 402, 206, - 601, 0, 207, 0, 496, 603, 644, 449, 211, 233, - 234, 236, 0, 278, 282, 290, 293, 302, 303, 312, - 364, 416, 443, 439, 448, 0, 574, 595, 608, 619, - 625, 626, 628, 629, 630, 631, 632, 635, 633, 404, - 310, 492, 332, 370, 0, 0, 422, 469, 239, 599, - 493, 199, 0, 0, 0, 0, 253, 254, 0, 570, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 645, - 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 659, 660, 661, 662, 640, 503, 509, - 504, 505, 506, 507, 508, 0, 510, 0, 0, 0, - 0, 0, 395, 0, 586, 587, 663, 381, 483, 596, - 334, 346, 349, 339, 358, 0, 359, 335, 336, 341, - 343, 344, 345, 350, 351, 355, 361, 248, 209, 387, - 396, 573, 311, 215, 216, 217, 519, 520, 521, 522, - 611, 612, 616, 204, 459, 460, 461, 462, 291, 606, - 308, 465, 464, 330, 331, 376, 446, 535, 537, 548, - 552, 554, 556, 562, 565, 536, 538, 549, 553, 555, - 557, 563, 566, 525, 527, 529, 531, 544, 543, 540, - 568, 569, 546, 551, 530, 542, 547, 560, 567, 564, - 524, 528, 532, 541, 559, 558, 539, 550, 561, 545, - 533, 526, 534, 0, 196, 220, 365, 0, 451, 287, - 641, 610, 481, 605, 205, 222, 0, 261, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 200, 208, 221, 231, 235, 242, 260, 275, 277, 284, - 297, 309, 317, 318, 321, 327, 377, 383, 384, 385, - 386, 406, 407, 408, 411, 414, 415, 418, 420, 421, - 424, 428, 432, 433, 434, 436, 438, 440, 452, 457, - 471, 472, 473, 474, 475, 478, 479, 485, 486, 487, - 488, 489, 497, 498, 511, 581, 583, 598, 617, 623, - 477, 300, 301, 441, 442, 313, 314, 637, 638, 299, - 593, 624, 591, 636, 618, 435, 375, 0, 0, 378, - 280, 304, 319, 0, 609, 499, 226, 463, 289, 250, - 0, 0, 210, 245, 229, 258, 273, 276, 323, 388, - 397, 426, 431, 295, 270, 243, 456, 240, 482, 514, - 515, 516, 518, 392, 265, 430, 393, 0, 373, 571, - 572, 315, 0, 523, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 413, 0, 0, 0, 0, - 0, 0, 0, 0, 269, 0, 0, 0, 0, 363, - 266, 0, 0, 427, 0, 203, 0, 484, 251, 374, - 371, 578, 281, 272, 268, 249, 316, 382, 425, 513, - 419, 0, 367, 0, 0, 494, 398, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 322, 247, 324, 202, 410, 495, 285, 0, - 0, 0, 0, 0, 194, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 244, 0, 0, - 0, 348, 357, 356, 337, 338, 340, 342, 347, 354, - 360, 0, 0, 602, 0, 0, 0, 264, 320, 271, - 263, 575, 0, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1438, 0, 296, 0, 399, - 256, 0, 450, 0, 0, 0, 620, 0, 0, 0, - 0, 0, 0, 0, 362, 0, 329, 197, 224, 0, - 0, 409, 458, 470, 0, 0, 0, 252, 0, 468, - 423, 597, 232, 283, 455, 429, 466, 437, 286, 0, - 0, 467, 369, 580, 447, 594, 621, 622, 262, 403, - 607, 517, 615, 639, 225, 259, 417, 502, 600, 491, - 394, 576, 577, 328, 490, 294, 201, 366, 627, 223, - 476, 368, 241, 230, 582, 604, 298, 288, 453, 634, - 212, 512, 592, 238, 480, 0, 0, 642, 246, 501, - 214, 589, 500, 390, 325, 326, 213, 0, 454, 267, - 292, 0, 0, 257, 412, 584, 585, 255, 643, 227, - 614, 219, 0, 613, 405, 579, 590, 391, 380, 218, - 588, 389, 379, 333, 352, 353, 279, 306, 444, 372, - 445, 305, 307, 401, 400, 402, 206, 601, 0, 207, - 0, 496, 603, 644, 449, 211, 233, 234, 236, 0, - 278, 282, 290, 293, 302, 303, 312, 364, 416, 443, - 439, 448, 0, 574, 595, 608, 619, 625, 626, 628, - 629, 630, 631, 632, 635, 633, 404, 310, 492, 332, - 370, 0, 0, 422, 469, 239, 599, 493, 199, 0, - 0, 0, 0, 253, 254, 0, 570, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 645, 646, 647, 648, - 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 659, 660, 661, 662, 640, 503, 509, 504, 505, 506, - 507, 508, 0, 510, 0, 0, 0, 0, 0, 395, - 0, 586, 587, 663, 381, 483, 596, 334, 346, 349, - 339, 358, 0, 359, 335, 336, 341, 343, 344, 345, - 350, 351, 355, 361, 248, 209, 387, 396, 573, 311, - 215, 216, 217, 519, 520, 521, 522, 611, 612, 616, - 204, 459, 460, 461, 462, 291, 606, 308, 465, 464, - 330, 331, 376, 446, 535, 537, 548, 552, 554, 556, - 562, 565, 536, 538, 549, 553, 555, 557, 563, 566, - 525, 527, 529, 531, 544, 543, 540, 568, 569, 546, - 551, 530, 542, 547, 560, 567, 564, 524, 528, 532, - 541, 559, 558, 539, 550, 561, 545, 533, 526, 534, - 0, 196, 220, 365, 0, 451, 287, 641, 610, 481, - 605, 205, 222, 0, 261, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 200, 208, 221, - 231, 235, 242, 260, 275, 277, 284, 297, 309, 317, - 318, 321, 327, 377, 383, 384, 385, 386, 406, 407, - 408, 411, 414, 415, 418, 420, 421, 424, 428, 432, - 433, 434, 436, 438, 440, 452, 457, 471, 472, 473, - 474, 475, 478, 479, 485, 486, 487, 488, 489, 497, - 498, 511, 581, 583, 598, 617, 623, 477, 300, 301, - 441, 442, 313, 314, 637, 638, 1437, 593, 624, 591, - 636, 618, 435, 375, 0, 0, 378, 280, 304, 319, - 0, 609, 499, 226, 463, 289, 250, 0, 0, 210, - 245, 229, 258, 273, 276, 323, 388, 397, 426, 431, - 295, 270, 243, 456, 240, 482, 514, 515, 516, 518, - 392, 265, 430, 393, 0, 373, 571, 572, 315, 0, - 523, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 413, 0, 0, 0, 0, 0, 0, 0, - 0, 269, 0, 0, 0, 0, 363, 266, 0, 0, - 427, 0, 203, 0, 484, 251, 374, 371, 578, 281, - 272, 268, 249, 316, 382, 425, 513, 419, 0, 367, - 0, 0, 494, 398, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 322, - 247, 324, 202, 410, 495, 285, 0, 0, 0, 0, - 0, 194, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 244, 0, 0, 0, 348, 357, - 356, 337, 338, 340, 342, 347, 354, 360, 0, 0, - 602, 0, 0, 0, 264, 320, 271, 263, 575, 0, - 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 296, 0, 399, 256, 0, 450, - 0, 0, 0, 620, 0, 0, 0, 0, 0, 0, - 0, 362, 0, 329, 197, 224, 0, 0, 409, 458, - 470, 0, 0, 0, 252, 0, 468, 423, 597, 232, - 283, 455, 429, 466, 437, 286, 0, 0, 467, 369, - 580, 447, 594, 621, 622, 262, 403, 607, 517, 615, - 639, 225, 259, 417, 502, 600, 491, 394, 576, 577, - 328, 490, 294, 201, 366, 627, 223, 476, 368, 241, - 230, 582, 604, 298, 288, 453, 634, 212, 512, 592, - 238, 480, 0, 0, 642, 246, 501, 214, 589, 500, - 390, 325, 326, 213, 0, 454, 267, 292, 0, 0, - 257, 412, 584, 585, 255, 643, 227, 614, 219, 0, - 613, 405, 579, 590, 391, 380, 218, 588, 389, 379, - 333, 352, 353, 279, 306, 444, 372, 445, 305, 307, - 401, 400, 402, 206, 601, 0, 207, 0, 496, 603, - 644, 449, 211, 233, 234, 236, 0, 278, 282, 290, - 293, 302, 303, 312, 364, 416, 443, 439, 448, 0, - 574, 595, 608, 619, 625, 626, 628, 629, 630, 631, - 632, 635, 633, 404, 310, 492, 332, 370, 0, 0, - 422, 469, 239, 599, 493, 199, 0, 0, 0, 0, - 253, 254, 0, 570, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, - 662, 640, 503, 509, 504, 505, 506, 507, 508, 0, - 510, 0, 0, 0, 0, 0, 395, 0, 586, 587, - 663, 381, 483, 596, 334, 346, 349, 339, 358, 0, - 359, 335, 336, 341, 343, 344, 345, 350, 351, 355, - 361, 248, 209, 387, 396, 573, 311, 215, 216, 217, - 519, 520, 521, 522, 611, 612, 616, 204, 459, 460, - 461, 462, 291, 606, 308, 465, 464, 330, 331, 376, - 446, 535, 537, 548, 552, 554, 556, 562, 565, 536, - 538, 549, 553, 555, 557, 563, 566, 525, 527, 529, - 531, 544, 543, 540, 568, 569, 546, 551, 530, 542, - 547, 560, 567, 564, 524, 528, 532, 541, 559, 558, - 539, 550, 561, 545, 533, 526, 534, 0, 196, 220, - 365, 0, 451, 287, 641, 610, 481, 605, 205, 222, - 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1036, - 0, 0, 0, 198, 200, 208, 221, 231, 235, 242, - 260, 275, 277, 284, 297, 309, 317, 318, 321, 327, - 377, 383, 384, 385, 386, 406, 407, 408, 411, 414, - 415, 418, 420, 421, 424, 428, 432, 433, 434, 436, - 438, 440, 452, 457, 471, 472, 473, 474, 475, 478, - 479, 485, 486, 487, 488, 489, 497, 498, 511, 581, - 583, 598, 617, 623, 477, 300, 301, 441, 442, 313, - 314, 637, 638, 299, 593, 624, 591, 636, 618, 435, - 375, 0, 0, 378, 280, 304, 319, 0, 609, 499, - 226, 463, 289, 250, 0, 0, 210, 245, 229, 258, - 273, 276, 323, 388, 397, 426, 431, 295, 270, 243, - 456, 240, 482, 514, 515, 516, 518, 392, 265, 430, - 393, 0, 373, 571, 572, 315, 0, 523, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 413, - 0, 0, 0, 0, 0, 0, 0, 0, 269, 0, - 0, 0, 0, 363, 266, 0, 0, 427, 0, 203, - 0, 484, 251, 374, 371, 578, 281, 272, 268, 249, - 316, 382, 425, 513, 419, 0, 367, 0, 0, 494, - 398, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 322, 247, 324, 202, - 410, 495, 285, 0, 0, 0, 0, 0, 194, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 244, 0, 0, 0, 348, 357, 356, 337, 338, - 340, 342, 347, 354, 360, 0, 0, 602, 0, 0, - 0, 264, 320, 271, 263, 575, 0, 0, 0, 0, - 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 296, 0, 399, 256, 0, 450, 0, 666, 0, - 620, 0, 0, 0, 0, 0, 0, 0, 362, 0, - 329, 197, 224, 0, 0, 409, 458, 470, 0, 0, - 0, 252, 0, 468, 423, 597, 232, 283, 455, 429, - 466, 437, 286, 0, 0, 467, 369, 580, 447, 594, - 621, 622, 262, 403, 607, 517, 615, 639, 225, 259, - 417, 502, 600, 491, 394, 576, 577, 328, 490, 294, - 201, 366, 627, 223, 476, 368, 241, 230, 582, 604, - 298, 288, 453, 634, 212, 512, 592, 238, 480, 0, - 0, 642, 246, 501, 214, 589, 500, 390, 325, 326, - 213, 0, 454, 267, 292, 0, 0, 257, 412, 584, - 585, 255, 643, 227, 614, 219, 0, 613, 405, 579, - 590, 391, 380, 218, 588, 389, 379, 333, 352, 353, - 279, 306, 444, 372, 445, 305, 307, 401, 400, 402, - 206, 601, 0, 207, 0, 496, 603, 644, 449, 211, - 233, 234, 236, 0, 278, 282, 290, 293, 302, 303, - 312, 364, 416, 443, 439, 448, 0, 574, 595, 608, - 619, 625, 626, 628, 629, 630, 631, 632, 635, 633, - 404, 310, 492, 332, 370, 0, 0, 422, 469, 239, - 599, 493, 199, 0, 0, 0, 0, 253, 254, 0, - 570, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 659, 660, 661, 662, 640, 503, - 509, 504, 505, 506, 507, 508, 0, 510, 0, 0, - 0, 0, 0, 395, 0, 586, 587, 663, 381, 483, - 596, 334, 346, 349, 339, 358, 0, 359, 335, 336, - 341, 343, 344, 345, 350, 351, 355, 361, 248, 209, - 387, 396, 573, 311, 215, 216, 217, 519, 520, 521, - 522, 611, 612, 616, 204, 459, 460, 461, 462, 291, - 606, 308, 465, 464, 330, 331, 376, 446, 535, 537, - 548, 552, 554, 556, 562, 565, 536, 538, 549, 553, - 555, 557, 563, 566, 525, 527, 529, 531, 544, 543, - 540, 568, 569, 546, 551, 530, 542, 547, 560, 567, - 564, 524, 528, 532, 541, 559, 558, 539, 550, 561, - 545, 533, 526, 534, 0, 196, 220, 365, 0, 451, - 287, 641, 610, 481, 605, 205, 222, 0, 261, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 198, 200, 208, 221, 231, 235, 242, 260, 275, 277, - 284, 297, 309, 317, 318, 321, 327, 377, 383, 384, - 385, 386, 406, 407, 408, 411, 414, 415, 418, 420, - 421, 424, 428, 432, 433, 434, 436, 438, 440, 452, - 457, 471, 472, 473, 474, 475, 478, 479, 485, 486, - 487, 488, 489, 497, 498, 511, 581, 583, 598, 617, - 623, 477, 300, 301, 441, 442, 313, 314, 637, 638, - 299, 593, 624, 591, 636, 618, 435, 375, 0, 0, - 378, 280, 304, 319, 0, 609, 499, 226, 463, 289, - 250, 0, 0, 210, 245, 229, 258, 273, 276, 323, - 388, 397, 426, 431, 295, 270, 243, 456, 240, 482, - 514, 515, 516, 518, 392, 265, 430, 393, 0, 373, - 571, 572, 315, 0, 523, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 413, 0, 0, 0, - 0, 0, 0, 0, 0, 269, 0, 0, 0, 0, - 363, 266, 0, 0, 427, 0, 203, 0, 484, 251, - 374, 371, 578, 281, 272, 268, 249, 316, 382, 425, - 513, 419, 0, 367, 0, 0, 494, 398, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 322, 247, 324, 202, 410, 495, 285, - 0, 0, 0, 0, 0, 713, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 244, 0, - 0, 0, 348, 357, 356, 337, 338, 340, 342, 347, - 354, 360, 0, 0, 602, 0, 0, 0, 264, 320, - 271, 263, 575, 0, 0, 0, 0, 0, 0, 0, - 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, - 399, 256, 0, 450, 0, 0, 0, 620, 0, 0, - 0, 0, 0, 0, 0, 362, 0, 329, 197, 224, - 0, 0, 409, 458, 470, 0, 0, 0, 252, 0, - 468, 423, 597, 232, 283, 455, 429, 466, 437, 286, - 0, 0, 467, 369, 580, 447, 594, 621, 622, 262, - 403, 607, 517, 615, 639, 225, 259, 417, 502, 600, - 491, 394, 576, 577, 328, 490, 294, 201, 366, 627, - 223, 476, 368, 241, 230, 582, 604, 298, 288, 453, - 634, 212, 512, 592, 238, 480, 0, 0, 642, 246, - 501, 214, 589, 500, 390, 325, 326, 213, 0, 454, - 267, 292, 0, 0, 257, 412, 584, 585, 255, 643, - 227, 614, 219, 0, 613, 405, 579, 590, 391, 380, - 218, 588, 389, 379, 333, 352, 353, 279, 306, 444, - 372, 445, 305, 307, 401, 400, 402, 206, 601, 0, - 207, 0, 496, 603, 644, 449, 211, 233, 234, 236, - 0, 278, 282, 290, 293, 302, 303, 312, 364, 416, - 443, 439, 448, 0, 574, 595, 608, 619, 625, 626, - 628, 629, 630, 631, 632, 635, 633, 404, 310, 492, - 332, 370, 0, 0, 422, 469, 239, 599, 493, 199, - 0, 0, 0, 0, 253, 254, 0, 570, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 645, 646, 647, - 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, - 658, 659, 660, 661, 662, 640, 503, 509, 504, 505, - 506, 507, 508, 0, 510, 0, 0, 0, 0, 0, - 395, 0, 586, 587, 663, 381, 483, 596, 334, 346, - 349, 339, 358, 0, 359, 335, 336, 341, 343, 344, - 345, 350, 351, 355, 361, 248, 209, 387, 396, 573, - 311, 215, 216, 217, 519, 520, 521, 522, 611, 612, - 616, 204, 459, 460, 461, 462, 291, 606, 308, 465, - 464, 330, 331, 376, 446, 535, 537, 548, 552, 554, - 556, 562, 565, 536, 538, 549, 553, 555, 557, 563, - 566, 525, 527, 529, 531, 544, 543, 540, 568, 569, - 546, 551, 530, 542, 547, 560, 567, 564, 524, 528, - 532, 541, 559, 558, 539, 550, 561, 545, 533, 526, - 534, 0, 196, 220, 365, 0, 451, 287, 641, 610, - 481, 605, 205, 222, 0, 261, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 200, 208, - 221, 231, 235, 242, 260, 275, 277, 284, 297, 309, - 317, 318, 321, 327, 377, 383, 384, 385, 386, 4086, - 407, 408, 411, 414, 415, 418, 420, 421, 424, 428, - 432, 433, 434, 436, 438, 440, 452, 457, 471, 472, - 473, 474, 475, 478, 479, 485, 486, 487, 488, 489, - 497, 498, 511, 581, 583, 598, 617, 623, 477, 300, - 301, 441, 442, 313, 314, 637, 638, 299, 593, 624, - 591, 636, 618, 435, 375, 0, 0, 378, 280, 304, - 319, 0, 609, 499, 226, 463, 289, 250, 0, 0, - 210, 245, 229, 258, 273, 276, 323, 388, 397, 426, - 431, 295, 270, 243, 456, 240, 482, 514, 515, 516, - 518, 392, 265, 430, 393, 0, 373, 571, 572, 315, - 0, 523, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 413, 0, 0, 0, 0, 0, 0, - 0, 0, 269, 0, 0, 0, 0, 363, 266, 0, - 0, 427, 0, 203, 0, 484, 251, 374, 371, 578, - 281, 272, 268, 249, 316, 382, 425, 513, 419, 0, - 367, 0, 0, 494, 398, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 322, 247, 324, 202, 410, 495, 285, 0, 0, 0, - 0, 0, 713, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 244, 0, 0, 0, 348, - 357, 356, 337, 338, 340, 342, 347, 354, 360, 0, - 0, 602, 0, 0, 0, 264, 320, 271, 263, 575, - 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 296, 0, 399, 256, 0, - 450, 0, 0, 0, 620, 0, 0, 0, 0, 0, - 0, 0, 362, 0, 329, 197, 224, 0, 0, 409, - 458, 470, 0, 0, 0, 252, 0, 468, 423, 597, - 232, 283, 455, 429, 466, 437, 286, 0, 0, 467, - 369, 580, 447, 594, 621, 622, 262, 403, 607, 517, - 615, 639, 225, 259, 417, 502, 600, 491, 394, 576, - 577, 328, 490, 294, 201, 366, 627, 223, 476, 368, - 241, 230, 582, 604, 298, 288, 453, 634, 212, 512, - 592, 238, 480, 0, 0, 642, 246, 501, 214, 589, - 500, 390, 325, 326, 213, 0, 454, 267, 292, 0, - 0, 257, 412, 584, 585, 255, 643, 227, 614, 219, - 0, 613, 405, 579, 590, 391, 380, 218, 588, 389, - 379, 333, 352, 353, 279, 306, 444, 372, 445, 305, - 307, 401, 400, 402, 206, 601, 0, 207, 0, 496, - 603, 644, 449, 211, 233, 234, 236, 0, 278, 282, - 290, 293, 302, 303, 312, 364, 416, 443, 439, 448, - 0, 574, 595, 608, 619, 625, 626, 628, 629, 630, - 631, 632, 635, 633, 404, 310, 492, 332, 370, 0, - 0, 422, 469, 239, 599, 493, 199, 0, 0, 0, - 0, 253, 254, 0, 570, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, - 661, 662, 640, 503, 509, 504, 505, 506, 507, 508, - 0, 510, 0, 0, 0, 0, 0, 395, 0, 586, - 587, 663, 381, 483, 596, 334, 346, 349, 339, 358, - 0, 359, 335, 336, 341, 343, 344, 345, 350, 351, - 355, 361, 248, 209, 387, 396, 573, 311, 215, 216, - 217, 519, 520, 521, 522, 611, 612, 616, 204, 459, - 460, 461, 462, 291, 606, 308, 465, 464, 330, 331, - 376, 446, 535, 537, 548, 552, 554, 556, 562, 565, - 536, 538, 549, 553, 555, 557, 563, 566, 525, 527, - 529, 531, 544, 543, 540, 568, 569, 546, 551, 530, - 542, 547, 560, 567, 564, 524, 528, 532, 541, 559, - 558, 539, 550, 561, 545, 533, 526, 534, 0, 196, - 220, 365, 0, 451, 287, 641, 610, 481, 605, 205, - 222, 0, 261, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 200, 208, 221, 231, 235, - 242, 260, 275, 277, 284, 297, 309, 317, 318, 321, - 327, 377, 383, 384, 385, 386, 406, 407, 408, 411, - 414, 415, 418, 420, 421, 424, 428, 432, 433, 434, - 436, 438, 440, 452, 457, 471, 472, 473, 474, 475, - 478, 479, 485, 486, 487, 488, 489, 497, 498, 511, - 581, 583, 598, 617, 623, 477, 300, 301, 441, 442, - 313, 314, 637, 638, 299, 593, 624, 591, 636, 618, - 435, 375, 0, 0, 378, 280, 304, 319, 0, 609, - 499, 226, 463, 289, 250, 0, 0, 210, 245, 229, - 258, 273, 276, 323, 388, 397, 426, 431, 295, 270, - 243, 456, 240, 482, 514, 515, 516, 518, 392, 265, - 430, 393, 0, 373, 571, 572, 315, 0, 523, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 413, 0, 0, 0, 0, 0, 0, 0, 0, 269, - 0, 0, 0, 0, 363, 266, 0, 0, 427, 0, - 203, 0, 484, 251, 374, 371, 578, 281, 272, 268, - 249, 316, 382, 425, 513, 419, 0, 367, 0, 0, - 494, 398, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 322, 247, 324, - 202, 410, 495, 285, 0, 0, 0, 0, 0, 946, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 244, 0, 0, 0, 348, 357, 356, 337, - 338, 340, 342, 347, 354, 360, 0, 0, 602, 0, - 0, 0, 264, 320, 271, 263, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 296, 0, 399, 256, 0, 450, 0, 0, - 0, 620, 0, 0, 0, 0, 0, 0, 0, 362, - 0, 329, 197, 224, 0, 0, 409, 458, 470, 0, - 0, 0, 252, 0, 468, 423, 597, 232, 283, 455, - 429, 466, 437, 286, 0, 0, 467, 369, 580, 447, - 594, 621, 622, 262, 403, 607, 517, 615, 639, 225, - 259, 417, 502, 600, 491, 394, 576, 577, 328, 490, - 294, 201, 366, 627, 223, 476, 368, 241, 230, 582, - 604, 298, 288, 453, 634, 212, 512, 592, 238, 480, - 0, 0, 642, 246, 501, 214, 589, 500, 390, 325, - 326, 213, 0, 454, 267, 292, 0, 0, 257, 412, - 584, 585, 255, 643, 227, 614, 219, 0, 613, 405, - 579, 590, 391, 380, 218, 588, 389, 379, 333, 352, - 353, 279, 306, 444, 372, 445, 305, 307, 401, 400, - 402, 206, 601, 0, 207, 0, 496, 603, 644, 449, - 211, 233, 234, 236, 0, 278, 282, 290, 293, 302, - 303, 312, 364, 416, 443, 439, 448, 0, 574, 595, - 608, 619, 625, 626, 628, 629, 630, 631, 632, 635, - 633, 404, 310, 492, 332, 370, 0, 0, 422, 469, - 239, 599, 493, 199, 0, 0, 0, 0, 253, 254, - 0, 570, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 645, 646, 647, 648, 649, 650, 651, 652, 653, - 654, 655, 656, 657, 658, 659, 660, 661, 662, 640, - 503, 509, 504, 505, 506, 507, 508, 0, 510, 0, - 0, 0, 0, 0, 395, 0, 586, 587, 663, 381, - 483, 596, 334, 346, 349, 339, 358, 0, 359, 335, - 336, 341, 343, 344, 345, 350, 351, 355, 361, 248, - 209, 387, 396, 573, 311, 215, 216, 217, 519, 520, - 521, 522, 611, 612, 616, 204, 459, 460, 461, 462, - 291, 606, 308, 465, 464, 330, 331, 376, 446, 535, - 537, 548, 552, 554, 556, 562, 565, 536, 538, 549, - 553, 555, 557, 563, 566, 525, 527, 529, 531, 544, - 543, 540, 568, 569, 546, 551, 530, 542, 547, 560, - 567, 564, 524, 528, 532, 541, 559, 558, 539, 550, - 561, 545, 533, 526, 534, 0, 196, 220, 365, 0, - 451, 287, 641, 610, 481, 605, 205, 222, 0, 261, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 200, 208, 221, 231, 235, 242, 260, 275, - 277, 284, 297, 309, 317, 318, 321, 327, 377, 383, - 384, 385, 386, 406, 407, 408, 411, 414, 415, 418, - 420, 421, 424, 428, 432, 433, 434, 436, 438, 440, - 452, 457, 471, 472, 473, 474, 475, 478, 479, 485, - 486, 487, 488, 489, 497, 498, 511, 581, 583, 598, - 617, 623, 477, 300, 301, 441, 442, 313, 314, 637, - 638, 299, 593, 624, 591, 636, 618, 435, 375, 0, - 0, 378, 280, 304, 319, 0, 609, 499, 226, 463, - 289, 250, 0, 0, 210, 245, 229, 258, 273, 276, - 323, 388, 397, 426, 431, 295, 270, 243, 456, 240, - 482, 514, 515, 516, 518, 392, 265, 430, 393, 0, - 373, 571, 572, 315, 0, 523, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 413, 0, 0, - 0, 0, 0, 0, 0, 0, 269, 0, 0, 0, - 0, 363, 266, 0, 0, 427, 0, 203, 0, 484, - 251, 374, 371, 578, 281, 272, 268, 249, 316, 382, - 425, 513, 419, 0, 367, 0, 0, 494, 398, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 322, 247, 324, 202, 410, 495, - 285, 0, 0, 0, 0, 0, 194, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 244, - 0, 0, 0, 348, 357, 356, 337, 338, 340, 342, - 347, 354, 360, 0, 0, 602, 0, 0, 0, 264, - 320, 271, 263, 575, 0, 0, 0, 0, 0, 0, - 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, - 0, 399, 256, 0, 450, 0, 0, 0, 620, 0, - 0, 0, 0, 0, 0, 0, 362, 0, 329, 197, - 224, 0, 0, 409, 458, 470, 0, 0, 0, 252, - 0, 468, 423, 597, 232, 283, 455, 429, 466, 437, - 286, 0, 0, 467, 369, 580, 447, 594, 621, 622, - 262, 403, 607, 517, 615, 639, 225, 259, 417, 502, - 600, 491, 394, 576, 577, 328, 490, 294, 201, 366, - 627, 223, 476, 368, 241, 230, 582, 604, 298, 288, - 453, 634, 212, 512, 592, 238, 480, 0, 0, 642, - 246, 501, 214, 589, 500, 390, 325, 326, 213, 0, - 454, 267, 292, 0, 0, 257, 412, 584, 585, 255, - 643, 227, 614, 219, 0, 613, 405, 579, 590, 391, - 380, 218, 588, 389, 379, 333, 352, 353, 279, 306, - 444, 372, 445, 305, 307, 401, 400, 402, 206, 601, - 0, 207, 0, 496, 603, 644, 449, 211, 233, 234, - 236, 0, 278, 282, 290, 293, 302, 303, 312, 364, - 416, 443, 439, 448, 0, 574, 595, 608, 619, 625, - 626, 628, 629, 630, 631, 632, 635, 633, 404, 310, - 492, 332, 370, 0, 0, 422, 469, 239, 599, 493, - 199, 0, 0, 0, 0, 253, 254, 0, 570, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 645, 646, - 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, - 657, 658, 659, 660, 661, 662, 640, 503, 509, 504, - 505, 506, 507, 508, 0, 510, 0, 0, 0, 0, - 0, 395, 0, 586, 587, 663, 381, 483, 596, 334, - 346, 349, 339, 358, 0, 359, 335, 336, 341, 343, - 344, 345, 350, 351, 355, 361, 248, 209, 387, 396, - 573, 311, 215, 216, 217, 519, 520, 521, 522, 611, - 612, 616, 204, 459, 460, 461, 462, 291, 606, 308, - 465, 464, 330, 331, 376, 446, 535, 537, 548, 552, - 554, 556, 562, 565, 536, 538, 549, 553, 555, 557, - 563, 566, 525, 527, 529, 531, 544, 543, 540, 568, - 569, 546, 551, 530, 542, 547, 560, 567, 564, 524, - 528, 532, 541, 559, 558, 539, 550, 561, 545, 533, - 526, 534, 0, 196, 220, 365, 0, 451, 287, 641, - 610, 481, 605, 205, 222, 0, 261, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 200, - 208, 221, 231, 235, 242, 260, 275, 277, 284, 297, - 309, 317, 318, 321, 327, 377, 383, 384, 385, 386, - 406, 407, 408, 411, 414, 415, 418, 420, 421, 424, - 428, 432, 433, 434, 436, 438, 440, 452, 457, 471, - 472, 473, 474, 475, 478, 479, 485, 486, 487, 488, - 489, 497, 498, 511, 581, 583, 598, 617, 623, 477, - 300, 301, 441, 442, 313, 314, 637, 638, 299, 593, - 624, 591, 636, 618, 435, 375, 0, 0, 378, 280, - 304, 319, 0, 609, 499, 226, 463, 289, 250, 0, - 0, 210, 245, 229, 258, 273, 276, 323, 388, 397, - 426, 431, 295, 270, 243, 456, 240, 482, 514, 515, - 516, 518, 392, 265, 430, 0, 0, 373, 571, 572, - 315, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 2395, 0, 0, + 2394, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 2342, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 1936, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 2340, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 1081, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 1087, 330, 197, 225, 1085, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 2342, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 1936, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 1730, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 3687, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 2103, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2104, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 2842, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2843, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 2827, 0, 0, 0, 0, + 238, 0, 0, 245, 2828, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 1776, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 1775, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 717, 718, 719, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 4029, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 1936, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 3687, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 2396, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 1757, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 2050, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 2041, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 1903, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 1901, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 1899, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 1897, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 1895, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 1891, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 1889, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 1887, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 1862, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 1761, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 95, 0, 0, 0, + 948, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1440, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 1439, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1038, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 668, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 4095, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 948, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 394, + 0, 374, 573, 574, 316, 0, 0, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, + 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, + 0, 0, 364, 267, 0, 0, 204, 503, 0, 428, + 0, 203, 0, 485, 252, 375, 372, 580, 282, 273, + 269, 250, 317, 383, 426, 515, 420, 0, 368, 0, + 0, 495, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 323, 248, + 325, 202, 411, 496, 286, 0, 0, 0, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 238, 0, 0, 245, 0, 0, 0, 349, 358, 357, + 338, 339, 341, 343, 348, 355, 361, 0, 0, 604, + 0, 0, 0, 265, 321, 272, 264, 577, 0, 0, + 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 297, 0, 400, 257, 0, 451, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, + 363, 0, 330, 197, 225, 0, 0, 410, 459, 471, + 0, 0, 0, 253, 0, 469, 424, 599, 233, 284, + 456, 430, 467, 438, 287, 0, 0, 468, 370, 582, + 448, 596, 623, 624, 263, 404, 609, 519, 617, 641, + 226, 260, 418, 504, 602, 492, 395, 578, 579, 329, + 491, 295, 201, 367, 629, 224, 477, 369, 242, 231, + 584, 606, 299, 289, 454, 636, 213, 514, 594, 239, + 481, 0, 0, 644, 247, 502, 215, 591, 501, 391, + 326, 327, 214, 0, 455, 268, 293, 0, 0, 258, + 413, 586, 587, 256, 645, 228, 616, 220, 0, 615, + 406, 581, 592, 392, 381, 219, 590, 390, 380, 334, + 353, 354, 280, 307, 445, 373, 446, 306, 308, 402, + 401, 403, 207, 603, 0, 208, 0, 497, 605, 646, + 450, 212, 234, 235, 237, 0, 279, 283, 291, 294, + 303, 304, 313, 365, 417, 444, 440, 449, 0, 576, + 597, 610, 621, 627, 628, 630, 631, 632, 633, 634, + 637, 635, 405, 311, 493, 333, 371, 0, 0, 423, + 470, 240, 601, 494, 199, 0, 0, 0, 0, 254, + 255, 0, 572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 642, 505, 511, 506, 507, 508, 509, 510, 0, 512, + 0, 0, 0, 0, 0, 396, 0, 588, 589, 665, + 382, 484, 598, 335, 347, 350, 340, 359, 0, 360, + 336, 337, 342, 344, 345, 346, 351, 352, 356, 362, + 249, 210, 388, 397, 575, 312, 216, 217, 218, 521, + 522, 523, 524, 613, 614, 618, 205, 460, 461, 462, + 463, 292, 608, 309, 466, 465, 331, 332, 377, 447, + 537, 539, 550, 554, 556, 558, 564, 567, 538, 540, + 551, 555, 557, 559, 565, 568, 527, 529, 531, 533, + 546, 545, 542, 570, 571, 548, 553, 532, 544, 549, + 562, 569, 566, 526, 530, 534, 543, 561, 560, 541, + 552, 563, 547, 535, 528, 536, 0, 196, 221, 366, + 0, 452, 288, 643, 612, 482, 607, 206, 223, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 198, 200, 209, 222, 232, 236, 243, 261, + 276, 278, 285, 298, 310, 318, 319, 322, 328, 378, + 384, 385, 386, 387, 407, 408, 409, 412, 415, 416, + 419, 421, 422, 425, 429, 433, 434, 435, 437, 439, + 441, 453, 458, 472, 473, 474, 475, 476, 479, 480, + 486, 487, 488, 489, 490, 498, 499, 513, 583, 585, + 600, 619, 625, 478, 301, 302, 442, 443, 314, 315, + 639, 640, 300, 595, 626, 593, 638, 620, 436, 376, + 0, 0, 379, 281, 305, 320, 0, 611, 500, 227, + 464, 290, 251, 0, 0, 211, 246, 230, 259, 274, + 277, 324, 389, 398, 427, 432, 296, 271, 244, 457, + 241, 483, 516, 517, 518, 520, 393, 266, 431, 0, + 0, 374, 573, 574, 316, } var yyPact = [...]int{ - -1000, -1000, 1962, -1000, -533, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 5004, -1000, -538, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 2687, 2535, -1000, -1000, -1000, -1000, 2740, -1000, 1030, + 2183, -1000, 2515, 5017, -1000, 55465, 510, -1000, 52545, -445, + 881, 268, 36485, -1000, 200, -1000, 193, 54005, 204, -1000, + -1000, -1000, -1000, -445, 21885, 2408, 51, 43, 55465, -1000, + -1000, -1000, -1000, -364, 2671, 2153, -1000, 408, -1000, -1000, + -1000, -1000, -1000, -1000, 51815, -1000, 1184, -1000, -1000, 2520, + 2504, 2384, 928, 2400, -1000, 2576, 2153, -1000, 21885, 2673, + 2458, 21155, 21155, 478, -1000, -1000, 271, -1000, -1000, 31375, + 55465, 39405, 317, -1000, 2515, -1000, -1000, -1000, 202, -1000, + 346, 2073, -1000, 2065, -1000, 1014, 1053, 413, 846, 829, + 411, 410, 393, 391, 384, 381, 379, 376, 421, -1000, + 952, 952, -201, -205, 362, 479, 468, 468, 1044, 490, + 2493, 2479, -1000, -1000, 952, 952, 952, 343, 952, 952, + 952, 952, 323, 320, 952, 952, 952, 952, 952, 952, + 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, + 952, 909, 2515, 310, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 2398, 2471, -1000, -1000, -1000, -1000, 2579, -1000, 1052, - 2098, -1000, 2371, 6321, -1000, 55304, 770, -1000, 52396, -441, - 885, 254, 36402, -1000, 201, -1000, 194, 53850, 197, -1000, - -1000, -1000, -1000, -441, 21862, 2321, 72, 62, 55304, -1000, - -1000, -1000, -1000, -361, 2549, 2050, -1000, 378, -1000, -1000, - -1000, -1000, -1000, -1000, 51669, -1000, 1203, -1000, -1000, 2377, - 2359, 2309, 942, 2322, -1000, 2492, 2050, -1000, 21862, 2532, - 2449, 21135, 21135, 449, -1000, -1000, 276, -1000, -1000, 31313, - 55304, 39310, 287, -1000, 2371, -1000, -1000, -1000, 216, -1000, - 334, 1978, -1000, 1973, -1000, 919, 1089, 396, 863, 474, - 395, 394, 380, 379, 377, 370, 365, 359, 354, -1000, - 991, 991, -204, -210, 388, 467, 445, 445, 1100, 498, - 2345, 2344, -1000, -1000, 991, 991, 991, 349, 991, 991, - 991, 991, 303, 298, 991, 991, 991, 991, 991, 991, - 991, 991, 991, 991, 991, 991, 991, 991, 991, 991, - 991, 897, 2371, 284, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -7342,68 +7365,68 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 55465, 262, 55465, -1000, + 821, 509, -1000, -1000, -449, 1113, 1113, 77, 1113, 1113, + 1113, 1113, 185, 1006, 41, -1000, 182, 305, 168, 303, + 1087, 197, -1000, -1000, 292, 1087, 1945, -1000, 933, 287, + 169, -1000, 1113, 1113, -1000, 14561, 251, 14561, 14561, -1000, + 2503, -1000, -1000, -1000, -1000, -1000, 1426, -1000, -1000, -1000, + -1000, -26, 489, -1000, -1000, -1000, -1000, 54005, 51085, 289, + -1000, -1000, 771, 1967, 1182, 21885, 1367, 926, -1000, -1000, + 1487, 902, -1000, -1000, -1000, -1000, -1000, 802, -1000, 24075, + 24075, 24075, 24075, -1000, -1000, 2081, 50355, 2081, 2081, 24075, + 2081, 24075, 2081, 2081, 2081, 2081, 21885, 2081, 2081, 2081, + 2081, -1000, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, -1000, + -1000, -1000, -1000, 2081, 820, 2081, 2081, 2081, 2081, 2081, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2081, 2081, 2081, + 2081, 2081, 2081, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, -1000, -1000, -1000, 1800, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 26995, 1695, 1693, + 1692, -1000, 18965, 2081, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 55304, 217, 55304, -1000, 838, 767, - -1000, -1000, -445, 1108, 1108, 108, 1108, 1108, 1108, 1108, - 196, 963, 56, -1000, 191, 272, 188, 279, 1092, 206, - -1000, -1000, 268, 1092, 1855, -1000, 948, 278, 168, -1000, - 1108, 1108, -1000, 14568, 236, 14568, 14568, -1000, 2366, -1000, - -1000, -1000, -1000, -1000, 1360, -1000, -1000, -1000, -1000, -29, - 495, -1000, -1000, -1000, -1000, 53850, 50942, 235, -1000, -1000, - 343, 1652, 1400, 21862, 1459, 926, -1000, -1000, 1308, 902, - -1000, -1000, -1000, -1000, -1000, 800, -1000, 24043, 24043, 24043, - 24043, -1000, -1000, 1981, 50215, 1981, 1981, 24043, 1981, 24043, - 1981, 1981, 1981, 1981, 21862, 1981, 1981, 1981, 1981, -1000, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, -1000, -1000, -1000, - -1000, 1981, 837, 1981, 1981, 1981, 1981, 1981, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1981, 1981, 1981, 1981, 1981, - 1981, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, -1000, -1000, -1000, 1758, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 26951, 1651, 1647, 1607, -1000, - 18954, 1981, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 55465, -1000, 2081, 225, 54005, + 54005, 348, 1414, -1000, -1000, 2576, 2153, -1000, 2671, 2705, + 408, -1000, 2509, 1753, 1798, 1625, 2153, 2030, 55465, -1000, + 2102, -1000, -1000, -1000, -307, -329, 2258, 1574, 1934, -1000, + -1000, -1000, -1000, 2482, 21885, -1000, -1000, 2720, -1000, 28455, + 818, 2718, 49625, -1000, 478, 478, 2064, 424, 5, -1000, + -1000, -1000, -1000, 992, 35755, -1000, -1000, -1000, -1000, -1000, + 1953, 55465, -1000, -1000, 1216, 54005, -1000, 2181, -1000, 1949, + -1000, 2138, 21885, 2191, 508, 54005, 499, 498, 497, -1000, + -53, -1000, -1000, -1000, -1000, -1000, -1000, 952, 952, 952, + -1000, 399, 2660, 5017, 7766, -1000, -1000, -1000, 48895, 2178, + 54005, -1000, 2174, -1000, 1073, 872, 851, 851, 54005, -1000, + -1000, 54735, 54005, 1067, 1064, 54005, 54005, 54005, 54005, -1000, + 48165, -1000, 47435, 46705, 1413, 54005, 45975, 45245, 44515, 43785, + 43055, -1000, 2255, -1000, 2137, -1000, -1000, -1000, 54735, 54005, + 54005, 54735, 54005, 54735, 55465, 54005, -1000, -1000, 357, -1000, + -1000, 1411, 1397, 1396, 952, 952, 1395, 1929, 1927, 1926, + 952, 952, 1390, 1925, 37945, 1923, 276, 1383, 1381, 1349, + 1380, 1906, 299, 1895, 1379, 1310, 1348, 54005, 2171, 55465, + -1000, 290, 934, 907, 989, 2515, 2405, 2060, 488, 507, + 54005, 472, 472, 54005, -1000, 15297, 55465, 232, -1000, 1893, + 21885, -1000, 1089, 1087, 1087, -1000, -1000, -1000, -1000, -1000, + -1000, 1113, 55465, 1089, -1000, -1000, -1000, 1087, 1113, 55465, + 1113, 1113, 1113, 1113, 1087, 1087, 1087, 1113, 55465, 55465, + 55465, 55465, 55465, 55465, 55465, 55465, 55465, 14561, 933, 1113, + -450, -1000, 1881, -1000, -1000, -1000, 2283, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 55304, -1000, 1981, 226, 53850, 53850, 400, - 1371, -1000, -1000, 2492, 2050, -1000, 2549, 2514, 378, -1000, - 3145, 1622, 1632, 1576, 2050, 1956, 55304, -1000, 2000, -1000, - -1000, -1000, -328, -371, 2199, 1606, 1854, -1000, -1000, -1000, - -1000, 2465, 21862, -1000, -1000, 2570, -1000, 28405, 836, 2568, - 49488, -1000, 449, 449, 1970, 430, 14, -1000, -1000, -1000, - -1000, 1020, 35675, -1000, -1000, -1000, -1000, -1000, 1848, 55304, - -1000, -1000, 4160, 53850, -1000, 2097, -1000, 1844, -1000, 2024, - 21862, 2072, 760, 53850, 515, 510, 476, -1000, -56, -1000, - -1000, -1000, -1000, -1000, -1000, 991, 991, 991, -1000, 308, - 2531, 6321, 7041, -1000, -1000, -1000, 48761, 2096, 53850, -1000, - 2093, -1000, 1124, 835, 874, 874, 53850, -1000, -1000, 54577, - 53850, 1114, 1113, 53850, 53850, 53850, 53850, -1000, 48034, -1000, - 47307, 46580, 1370, 53850, 45853, 45126, 44399, 43672, 42945, -1000, - 2219, -1000, 2057, -1000, -1000, -1000, 54577, 53850, 53850, 54577, - 53850, 54577, 55304, 53850, -1000, -1000, 401, -1000, -1000, 1366, - 1364, 1363, 991, 991, 1350, 1836, 1835, 1833, 991, 991, - 1342, 1832, 37856, 1825, 282, 1329, 1328, 1310, 1510, 1816, - 193, 1812, 1377, 1355, 1309, 53850, 2091, 55304, -1000, 257, - 1043, 953, 1011, 2371, 2319, 1967, 491, 759, 53850, 450, - 450, 53850, -1000, 15301, 55304, 255, -1000, 1808, 21862, -1000, - 1103, 1092, 1092, -1000, -1000, -1000, -1000, -1000, -1000, 1108, - 55304, 1103, -1000, -1000, -1000, 1092, 1108, 55304, 1108, 1108, - 1108, 1108, 1092, 1092, 1092, 1108, 55304, 55304, 55304, 55304, - 55304, 55304, 55304, 55304, 55304, 14568, 948, 1108, -446, -1000, - 1802, -1000, -1000, -1000, 2194, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -7418,334 +7441,334 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 14561, 14561, -1000, -1000, -1000, -1000, + -1000, 2058, -1000, 187, 13, 199, -1000, 42325, 501, 985, + -1000, 501, -1000, -1000, -1000, 2050, 41595, -1000, -452, -456, + -459, -460, -1000, -1000, -1000, -461, -462, -1000, -1000, -1000, + 21885, 21885, 21885, 21885, -255, -1000, 1471, 24075, 2473, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 21885, 216, 948, 24075, + 24075, 24075, 24075, 24075, 24075, 24075, 25535, 24805, 24075, 24075, + 24075, 24075, 24075, 24075, -1000, -1000, 33565, 5149, 5149, 902, + 902, 902, 902, -1000, -164, 2044, 54735, -1000, -1000, -1000, + 817, 21885, 21885, 902, -1000, 1221, 2197, 18965, 21885, 21885, + 21885, 21885, 964, 1182, 54735, 21885, -1000, 1625, -1000, -1000, + -1000, -1000, 1331, -1000, -1000, 1104, 2469, 2469, 2469, 2469, + 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, + 2469, 21885, 173, 173, 910, 21885, 21885, 21885, 21885, 21885, + 21885, 17505, 21885, 21885, 24075, 21885, 21885, 21885, 1625, 21885, + 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, + 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, + 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, + 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, + 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, + 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, + 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, + 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 1625, 21885, + 1656, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 16769, 21885, + 21885, 21885, 21885, 21885, -1000, -1000, -1000, -1000, -1000, -1000, + 21885, 21885, 21885, 21885, 21885, 21885, 21885, 21885, 1625, 21885, + 21885, 21885, 21885, 21885, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1917, 1563, 1616, 21885, -1000, + 2036, -1000, -190, 30645, 21885, 1857, 2717, 2213, 54005, -1000, + -1000, -1000, -1000, 2576, -1000, 2576, 1917, 2451, 2339, 21155, + -1000, -1000, 2451, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 1937, -1000, 55465, 2030, 2581, 54005, -1000, -355, + -1000, -367, 2330, 1848, 351, -1000, 21885, 21885, 2027, -1000, + 1597, 55465, -1000, -255, -1000, 40865, -1000, -1000, 13825, 55465, + 372, 55465, -1000, 29915, 40135, 283, -1000, 5, 2013, -1000, + 20, 11, 18235, 901, -1000, -1000, -1000, 362, 26265, 1970, + 901, 108, -1000, -1000, -1000, 2138, -1000, 2138, 2138, 2138, + 2138, 351, 351, 351, 351, -1000, -1000, -1000, -1000, -1000, + 2162, 2157, -1000, 2138, 2138, 2138, 2138, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 14568, 14568, -1000, -1000, -1000, -1000, -1000, 1964, - -1000, 189, 23, 195, -1000, 42218, 541, 1007, -1000, 541, - -1000, -1000, -1000, 1963, 41491, -1000, -449, -455, -457, -459, - -1000, -1000, -1000, -463, -465, -1000, -1000, -1000, 21862, 21862, - 21862, 21862, -251, -1000, 1323, 24043, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 21862, 249, 1159, 24043, 24043, 24043, 24043, - 24043, 24043, 24043, 25497, 24770, 24043, 24043, 24043, 24043, 24043, - 24043, -1000, -1000, 33494, 5084, 5084, 902, 902, 902, 902, - -1000, -168, 1960, 54577, -1000, -1000, -1000, 833, 21862, 21862, - 902, -1000, 1426, 1991, 18954, 21862, 21862, 21862, 21862, 1050, - 1400, 54577, 21862, -1000, 1576, -1000, -1000, -1000, -1000, 1341, - -1000, -1000, 1127, 2353, 2353, 2353, 2353, 21862, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 21862, 21862, 2353, 21862, 264, - 264, 734, 21862, 21862, 21862, 21862, 21862, 21862, 17500, 21862, - 21862, 24043, 21862, 21862, 21862, 1576, 21862, 21862, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 1576, 21862, 1532, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 16767, 21862, 21862, 21862, 21862, - 21862, -1000, -1000, -1000, -1000, -1000, -1000, 21862, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 1576, 21862, 21862, 21862, 21862, - 21862, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 1621, 1633, 1575, 21862, -1000, 1957, -1000, -186, - 30586, 21862, 1796, 2566, 2071, 53850, -1000, -1000, -1000, -1000, - 2492, -1000, 2492, 1621, 3097, 2254, 21135, -1000, -1000, 3097, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1801, - -1000, 55304, 1956, 2445, 53850, -1000, -309, -1000, -311, 2250, - 1795, 955, -1000, 21862, 21862, 1954, -1000, 1770, 55304, -1000, - -251, -1000, 40764, -1000, -1000, 13835, 55304, 352, 55304, -1000, - 29859, 40037, 331, -1000, 14, 1926, -1000, 20, 21, 18227, - 901, -1000, -1000, -1000, 388, 26224, 1880, 901, 118, -1000, - -1000, -1000, 2024, -1000, 2024, 2024, 2024, 2024, 955, 955, - 955, 955, -1000, -1000, -1000, -1000, -1000, 2087, 2065, -1000, - 2024, 2024, 2024, 2024, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 2151, 2151, 2151, 2150, 2150, 2142, + 2142, 451, -1000, 21885, 517, 39405, 2558, 1337, 1773, 290, + 474, 2211, 54005, 54005, 54005, 474, -1000, 1518, 1510, 1508, + -1000, -527, 2026, -1000, -1000, 2654, -1000, -1000, 1065, 1141, + 1119, 1090, 54005, 231, 356, -1000, 442, -1000, 39405, 54005, + 1063, 851, 54005, -1000, 54005, -1000, -1000, -1000, -1000, -1000, + 54005, -1000, -1000, 2020, -1000, 2049, 1180, 1103, 1162, 1094, + 2020, -1000, -1000, -169, 2020, -1000, 2020, -1000, 2020, -1000, + 2020, -1000, 2020, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 977, 301, -375, 54005, 231, 486, -1000, 485, + 33565, -1000, -1000, -1000, 33565, 33565, -1000, -1000, -1000, -1000, + 1841, 1825, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 2061, 2061, 2061, 2048, 2048, 2026, 2026, 427, -1000, - 21862, 486, 39310, 2427, 1304, 2659, 257, 455, 2066, 53850, - 53850, 53850, 455, -1000, 1486, 1484, 1446, -1000, -524, 1948, - -1000, -1000, 2524, -1000, -1000, 906, 1168, 1164, 894, 53850, - 232, 322, -1000, 440, -1000, 39310, 53850, 1098, 874, 53850, - -1000, 53850, -1000, -1000, -1000, -1000, -1000, 53850, -1000, -1000, - 1944, -1000, 1979, 1198, 1152, 1182, 1144, 1944, -1000, -1000, - -173, 1944, -1000, 1944, -1000, 1944, -1000, 1944, -1000, 1944, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 985, - 336, -369, 53850, 232, 480, -1000, 469, 33494, -1000, -1000, - -1000, 33494, 33494, -1000, -1000, -1000, -1000, 1791, 1783, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -509, 55465, -1000, 258, 983, 319, 313, 331, 55465, + 401, 2465, 2463, 2452, 2450, 2447, 2439, 349, 318, 55465, + 55465, 472, 2266, 55465, 2537, 55465, -1000, -1000, -1000, -1000, + -1000, 1811, 1806, -1000, 1182, 55465, -1000, -1000, 1113, 1113, + -1000, -1000, 55465, 1113, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 1113, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 55465, -1000, + -1000, -1000, -1000, -26, 181, -1000, -1000, 54005, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -110, -1000, 718, + 18, 383, -1000, -1000, -1000, -1000, -1000, 2588, -1000, 1182, + 1050, 1034, -1000, 2081, -1000, -1000, 1321, -1000, -1000, -1000, + -1000, -1000, 2081, 2081, 2081, -1000, -1000, -1000, -1000, -1000, + 216, 24075, 24075, 24075, 1469, 797, 1558, 1283, 1219, 1228, + 1228, 1013, 24075, 1013, 24075, 912, 912, 912, 912, 912, + -1000, -1000, -1000, -1000, -1000, -1000, 1800, -1000, 1786, -1000, + 2081, 54735, 1903, 16769, 2591, 1340, 1625, 921, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -508, 55304, - -1000, 252, 1004, 306, 310, 314, 55304, 375, 2480, 2479, - 2475, 2472, 2464, 2456, 248, 297, 55304, 55304, 450, 2168, - 55304, 2400, 55304, -1000, -1000, -1000, -1000, -1000, 1772, 1763, - -1000, 1400, 55304, -1000, -1000, 1108, 1108, -1000, -1000, 55304, - 1108, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1108, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3856, 1625, + 1967, 1625, 2021, 3538, 1024, -1000, 21885, 1625, 3502, -1000, + -1000, 1625, 1625, 21885, -1000, -1000, 21885, 21885, 21885, 21885, + 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, + 21885, 1773, 2018, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 55304, -1000, -1000, -1000, -1000, - -29, 187, -1000, -1000, 53850, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -108, -1000, 717, 26, 383, -1000, - -1000, -1000, -1000, -1000, 2489, -1000, 1400, 1077, 1078, -1000, - 1981, -1000, -1000, 1213, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 249, 24043, 24043, 24043, 1396, 840, - 1416, 1427, 1332, 1223, 1223, 1205, 24043, 1205, 24043, 907, - 907, 907, 907, 907, -1000, -1000, -1000, -1000, -1000, -1000, - 1758, -1000, 1753, -1000, 1981, 54577, 1790, 16767, 1405, 1965, - 1576, 921, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 2017, 2716, 2175, 1773, 1773, 1773, 1773, 1773, 21885, + 1461, -1000, -1000, -1000, 1628, 3490, 1366, 3473, 1773, 1773, + -1000, 1773, 3458, 3453, 1625, 2670, 2659, 1773, 1773, 1773, + 1773, 1773, 2601, 2572, 1773, 1773, 2543, 1773, 3448, 1773, + 2539, 2532, 2492, 2467, 2462, 2449, 2435, 2425, 2377, 2352, + 2333, 2327, 2314, 2301, 2287, 2269, 2257, 2253, 1773, 1773, + 1773, 3443, 1773, 3432, 1773, 3427, 1773, 1773, 3422, 2243, + 2206, 1625, 2016, -1000, 3415, 1773, 3399, 3386, 3382, 2167, + 3356, 3352, 3348, 1773, 1773, 1773, 2163, 3341, 3328, 3323, + 3313, 3308, 3236, 3224, 3043, 3030, 1773, 1616, 1616, 1616, + 1616, 1616, 3023, -269, 1773, 1625, -1000, -1000, -1000, -1000, + -1000, 3019, 2159, 3009, 3001, 2994, 2981, 1625, 2081, 814, + -1000, -1000, 1616, 1625, 1625, 1616, 1616, 2976, 2932, 2922, + 2918, 2912, 2908, 1773, 1773, -1000, 1773, 2895, 2846, 2139, + 2123, 1625, -1000, 1616, 55465, -1000, -441, -1000, 9, 960, + 2081, -1000, 37945, 1625, -1000, 4388, -1000, 1287, -1000, -1000, + -1000, -1000, -1000, 35025, 2023, -1000, -1000, -1000, -1000, 2081, + 1891, -1000, -1000, -1000, -1000, 351, 74, 34295, 878, 878, + 126, 1182, 1182, 21885, -1000, -1000, -1000, -1000, -1000, -1000, + 813, 2679, 394, 2081, -1000, 2066, 2723, -1000, -1000, -1000, + 2579, 27725, -1000, -1000, 2081, 2081, 55465, 1989, 1922, -1000, + 810, -1000, 1476, 2013, 5, 1, -1000, -1000, -1000, -1000, + 1182, -1000, 1438, 374, 341, -1000, 463, -1000, -1000, -1000, + -1000, 2420, 94, -1000, -1000, -1000, 373, 351, -1000, -1000, + -1000, -1000, -1000, -1000, 1736, 1736, -1000, -1000, -1000, -1000, + -1000, 1336, -1000, -1000, -1000, -1000, 1334, -1000, -1000, 1328, + -1000, -1000, 2712, 2195, 517, -1000, -1000, 952, 1734, -1000, + -1000, 2438, 952, 952, 54005, -1000, -1000, 1823, 2558, 258, + 55465, 1003, 2263, -1000, 2211, 2211, 2211, 55465, -1000, -1000, + -1000, -1000, -1000, -1000, -513, 172, 378, -1000, -1000, -1000, + 6167, 54005, 1889, -1000, 253, -1000, 1797, -1000, 54005, -1000, + 1865, 2149, 54005, 54005, -1000, -1000, -1000, 54005, 2081, -1000, + -1000, -1000, -1000, 504, 2511, 336, -1000, -1000, -311, -1000, + -1000, 231, 253, 54735, 54005, 901, -1000, -1000, -1000, -1000, + -1000, -514, 1856, 494, 263, 516, 55465, 55465, 55465, 55465, + 55465, 55465, 782, -1000, -1000, 31, -1000, -1000, 218, -1000, + -1000, -1000, -1000, -1000, 218, -1000, -1000, -1000, -1000, -1000, + 312, 484, -1000, 55465, 55465, 917, -1000, -1000, -1000, -1000, + -1000, 1087, -1000, -1000, 1087, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 2499, 55465, 17, -479, -1000, + -476, 21885, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1329, + 471, 1558, 24075, 24075, 2197, 2197, 24075, -1000, -1000, -1000, + 819, 819, 33565, -1000, 24075, 21885, -1000, -1000, 21885, 21885, + 21885, 949, -1000, 21885, 1137, -1000, 21885, -1000, -269, 1616, + 1773, 1773, 1773, 1773, -269, -269, -269, -269, -269, -269, + -269, -269, -269, -269, 2063, -1000, 21885, 21885, 21885, 1625, + 345, -1000, -1000, -1000, -1000, -1000, 2710, -1000, 21885, -1000, + 33565, 21885, 21885, 21885, -1000, -1000, -1000, 21885, 21885, -1000, + -1000, 21885, -1000, 21885, -1000, -1000, -1000, -1000, -1000, -1000, + 21885, -1000, 21885, -1000, -1000, -1000, 21885, -1000, 21885, -1000, + -1000, 21885, -1000, 21885, -1000, 21885, -1000, 21885, -1000, 21885, + -1000, 21885, -1000, 21885, -1000, 21885, -1000, 21885, -1000, 21885, + -1000, 21885, -1000, 21885, -1000, 21885, -1000, 21885, -1000, 21885, + -1000, 21885, -1000, 21885, -1000, 21885, -1000, -1000, -1000, 21885, + -1000, 21885, -1000, 21885, -1000, -1000, 21885, -1000, 21885, -1000, + 21885, -1000, 21885, 21885, -1000, 21885, 21885, 21885, -1000, 21885, + 21885, 21885, 21885, -1000, -1000, -1000, -1000, 21885, 21885, 21885, + 21885, 21885, 21885, 21885, 21885, 21885, 21885, -1000, -1000, -1000, + -1000, -1000, -1000, 21885, -1000, 39405, 10, -269, 1656, 10, + 1656, 23345, 823, 798, 22615, -1000, 21885, 16033, -1000, -1000, + -1000, -1000, -1000, 21885, 21885, 21885, 21885, 21885, 21885, -1000, + -1000, -1000, 21885, 21885, -1000, 21885, -1000, 21885, -1000, -1000, + -1000, -1000, -1000, 960, -1000, 883, 874, 851, 54005, -1000, + -1000, -1000, -1000, 2005, -1000, 2616, -1000, 2361, 2359, 2704, + 2679, 21155, -1000, 29915, -1000, -1000, 54005, -432, -1000, 2391, + 2399, 878, 878, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 13089, 2576, 21885, 2261, 54735, 249, -1000, 29185, 54005, 54735, + 29915, 29915, 29915, 29915, 29915, -1000, 2307, 2288, -1000, 2342, + 2311, 2338, 55465, -1000, 1917, 1838, -1000, 21885, 32105, 1975, + 29915, -1000, -1000, 29915, 55465, 12353, -1000, -1000, 16, 4, + -1000, -1000, -1000, -1000, 362, -1000, -1000, 1002, 2575, 2417, + -1000, -1000, -1000, -1000, -1000, 1758, -1000, 1749, 1995, 1745, + 1742, 301, -1000, 2190, 2497, 952, 952, -1000, 1327, -1000, + 1221, 1733, 1731, -1000, -1000, -1000, 492, -1000, 2536, 55465, + 2252, 2251, 2249, -1000, -524, 1314, 2148, 2172, 21885, 2145, + 2653, 1980, 54005, -1000, -1000, 54735, -1000, 282, -1000, 517, + 54005, -1000, -1000, -1000, 356, 55465, -1000, 8424, -1000, -1000, + -1000, 253, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 55465, + 270, -1000, 2143, 1425, -1000, -1000, 2196, -1000, -1000, -1000, + -1000, -1000, 210, 201, 1730, 214, 1716, 214, -1000, 55465, + 914, 2195, 55465, -1000, -1000, -1000, 1113, 1113, -1000, -1000, + 2475, -1000, 1221, 1773, 24075, 24075, -1000, 902, -1000, -1000, + 371, -254, 2138, 2138, -1000, 2138, 2142, -1000, 2138, 171, + 2138, 165, 2138, -1000, -1000, 1625, 1625, -1000, 1616, 2119, + 1200, 2841, -1000, 1182, 21885, 2831, -1000, -1000, -269, -269, + -269, -269, -269, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -60, 2787, 2750, 1773, -1000, 2132, 2128, + 21885, 1773, 1625, 2098, 1773, 1773, 1773, 1773, 1773, 1773, + 1773, 1773, 1773, 1773, 1773, 1773, 2090, 2061, 2056, 2047, + 2033, 2028, 2014, 1999, 1990, 1986, 1969, 1956, 1951, 1941, + 1905, 1879, 1773, 1773, 1860, 1773, 1854, 1822, -1000, 1182, + 1616, 2746, 1616, 1773, 1773, 2721, 306, 1773, 1727, 1727, + 1727, 1727, 1727, 1616, 1616, 1616, 1616, 1773, 54005, -1000, + -269, -1000, -1000, -374, -376, -1000, 1625, -269, 1993, 24075, + 1773, 24075, 24075, 24075, 1773, 1625, -1000, 1818, 1814, 2707, + 1796, 1773, 2681, 1773, 1773, 1773, 1789, -1000, 2586, 2081, + 2586, 2081, 2586, 1714, 1287, 55465, -1000, -1000, -1000, -1000, + 2679, 2677, -1000, 1984, -1000, 74, 629, -1000, 2376, 2399, + -1000, 2651, 2383, 2650, -1000, -1000, -1000, -1000, -1000, 1182, + -1000, 2518, 1966, -1000, 982, 1820, -1000, -1000, 20425, 1720, + 2353, 808, 1714, 2037, 2723, 2208, 2240, 3626, -1000, -1000, + -1000, -1000, 2281, -1000, 2221, -1000, -1000, 2102, -1000, 2638, + 372, 29915, 1998, 1998, -1000, 800, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 1160, 8424, 2727, -1000, 1710, -1000, 1372, + 191, 1309, -1000, -1000, 952, 952, -1000, 1057, 1056, -1000, + 55465, 2127, -1000, 351, 1697, 351, 1280, -1000, -1000, 1276, + -1000, -1000, -1000, -1000, 2099, 2242, -1000, -1000, -1000, -1000, + 55465, -1000, -1000, 55465, 55465, 55465, 2122, 2649, -1000, 21885, + 2116, 954, 2596, 54005, 54005, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 447, 952, -492, 316, + 302, 952, 952, 952, -526, -1000, -1000, 1709, 1705, -1000, + -202, -1000, 21885, -1000, -1000, -1000, -1000, -1000, 1201, 1201, + 1695, 1693, 1692, -1000, 2102, -1000, -1000, -1000, 1759, -1000, + -1000, -179, 54005, 54005, 54005, 54005, -1000, -1000, -1000, 1277, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 3864, 1576, 1652, 1576, 1276, 3853, 1058, -1000, - 21862, 1576, 3849, -1000, -1000, 1576, 1576, 21862, -1000, -1000, - 21862, 21862, 21862, 21862, 2659, 2659, 2659, 2659, 2659, 2659, - 2659, 2659, 2659, 2659, 21862, 2659, 1938, -1000, -1000, -1000, + -1000, -1000, 902, 1625, 387, -183, 1625, -1000, -1000, 351, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1935, 2564, 1313, 2659, 2659, - 2659, 2659, 2659, 21862, 2376, -1000, -1000, -1000, 1544, 3535, - 1356, 3531, 2659, 2659, -1000, 2659, 3521, 3516, 1576, 2644, - 2638, 2659, 2659, 2659, 2659, 2659, 2634, 2628, 2659, 2659, - 2621, 2659, 3499, 2659, 2614, 2596, 2577, 2545, 2539, 2534, - 2527, 2515, 2502, 2457, 2426, 2422, 2406, 2365, 2342, 2334, - 2323, 2274, 2659, 2659, 2659, 3489, 2659, 3484, 2659, 3472, - 2659, 2659, 3452, 2261, 2253, 1576, 1927, -1000, 3448, 2659, - 3435, 3427, 3421, 2243, 3411, 3388, 3377, 2659, 2659, 2659, - 2231, 3373, 3360, 3354, 3340, 3330, 3325, 3319, 3315, 3306, - 2659, 1575, 1575, 1575, 1575, 1575, 3302, -263, 2659, 1576, - -1000, -1000, -1000, -1000, -1000, 3293, 2217, 3229, 3087, 3064, - 3037, 1576, 1981, 832, -1000, -1000, 1575, 1576, 1576, 1575, - 1575, 3003, 2972, 2968, 2964, 2959, 2938, 2659, 2659, -1000, - 2659, 2929, 2907, 2174, 2166, 1576, -1000, 1575, 55304, -1000, - -440, -1000, -3, 956, 1981, -1000, 37856, 1576, -1000, 4361, - -1000, 1217, -1000, -1000, -1000, -1000, -1000, 34948, 1934, -1000, - -1000, -1000, -1000, 1981, 1779, -1000, -1000, -1000, -1000, 955, - 93, 34221, 884, 884, 127, 1400, 1400, 21862, -1000, -1000, - -1000, -1000, -1000, -1000, 831, 2555, 371, 1981, -1000, 1943, - 2676, -1000, -1000, -1000, 2444, 27678, -1000, -1000, 1981, 1981, - 55304, 1840, 1839, -1000, 826, -1000, 1430, 1926, 14, 46, - -1000, -1000, -1000, -1000, 1400, -1000, 1443, 355, 362, -1000, - 452, -1000, -1000, -1000, -1000, 2328, 105, -1000, -1000, -1000, - 374, 955, -1000, -1000, -1000, -1000, -1000, -1000, 1735, 1735, - -1000, -1000, -1000, -1000, -1000, 1292, -1000, -1000, -1000, -1000, - 1289, -1000, -1000, 1288, -1000, -1000, 2901, 2167, 486, -1000, - -1000, 991, 1733, -1000, -1000, 2330, 991, 991, 53850, -1000, - -1000, 1866, 2427, 252, 55304, 1055, 2165, -1000, 2066, 2066, - 2066, 55304, -1000, -1000, -1000, -1000, -1000, -1000, -510, 186, - 514, -1000, -1000, -1000, 5102, 53850, 1752, -1000, 230, -1000, - 1861, -1000, 53850, -1000, 1750, 2047, 53850, 53850, -1000, -1000, - -1000, 53850, 1981, -1000, -1000, -1000, -1000, 528, 2368, 329, - -1000, -1000, -288, -1000, -1000, 232, 230, 54577, 53850, 901, - -1000, -1000, -1000, -1000, -1000, -511, 1747, 459, 241, 544, - 55304, 55304, 55304, 55304, 55304, 55304, 790, -1000, -1000, 40, - -1000, -1000, 218, -1000, -1000, -1000, -1000, -1000, 218, -1000, - -1000, -1000, -1000, -1000, 286, 466, -1000, 55304, 55304, 959, - -1000, -1000, -1000, -1000, -1000, 1092, -1000, -1000, 1092, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2364, - 55304, 8, -478, -1000, -474, 21862, -1000, -1000, -1000, -1000, - 1321, 828, 1416, 24043, 24043, 1991, 1991, 24043, -1000, -1000, - -1000, 1023, 1023, 33494, -1000, 24043, 21862, -1000, -1000, 21862, - 21862, 21862, 1022, -1000, 21862, 1291, -1000, 21862, -1000, -263, - 1575, 2659, 2659, 2659, 2659, -263, -263, -263, -263, -263, - -263, -263, -263, -263, -263, 1915, -1000, 21862, 21862, 21862, - 1576, 330, -1000, -1000, -1000, -1000, -1000, 2563, -1000, 21862, - -1000, 33494, 21862, 21862, 21862, -1000, -1000, -1000, 21862, 21862, - -1000, -1000, 21862, -1000, 21862, -1000, -1000, -1000, -1000, -1000, - -1000, 21862, -1000, 21862, -1000, -1000, -1000, 21862, -1000, 21862, - -1000, -1000, 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, - 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, - 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, - 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, -1000, -1000, - 21862, -1000, 21862, -1000, 21862, -1000, -1000, 21862, -1000, 21862, - -1000, 21862, -1000, 21862, 21862, -1000, 21862, 21862, 21862, -1000, - 21862, 21862, 21862, 21862, -1000, -1000, -1000, -1000, 21862, 21862, - 21862, 21862, 21862, 21862, 21862, 21862, 21862, 21862, -1000, -1000, - -1000, -1000, -1000, -1000, 21862, -1000, 39310, 19, -263, 1532, - 19, 1532, 23316, 829, 791, 22589, -1000, 21862, 16034, -1000, - -1000, -1000, -1000, -1000, 21862, 21862, 21862, 21862, 21862, 21862, - -1000, -1000, -1000, 21862, 21862, -1000, 21862, -1000, 21862, -1000, - -1000, -1000, -1000, -1000, 956, -1000, 458, 453, 874, 53850, - -1000, -1000, -1000, -1000, 1904, -1000, 2461, -1000, 2270, 2266, - 2562, 2555, 21135, -1000, 29859, -1000, -1000, 53850, -429, -1000, - 2308, 2291, 884, 884, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 13102, 2492, 21862, 2163, 54577, 251, -1000, 29132, 53850, - 54577, 29859, 29859, 29859, 29859, 29859, -1000, 2200, 2198, -1000, - 2236, 2214, 2277, 55304, -1000, 1621, 1745, -1000, 21862, 32040, - 1860, 29859, -1000, -1000, 29859, 55304, 12369, -1000, -1000, 3, - -4, -1000, -1000, -1000, -1000, 388, -1000, -1000, 1174, 2443, - 2325, -1000, -1000, -1000, -1000, -1000, 1741, -1000, 1731, 1901, - 1726, 1722, 336, -1000, 2043, 2361, 991, 991, -1000, 1275, - -1000, 1426, 1714, 1698, -1000, -1000, -1000, 456, -1000, 2397, - 55304, 2156, 2155, 2154, -1000, -522, 1272, 2037, 1968, 21862, - 2031, 2521, 1882, 53850, -1000, -1000, 54577, -1000, 262, -1000, - 486, 53850, -1000, -1000, -1000, 322, 55304, -1000, 8317, -1000, - -1000, -1000, 230, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 55304, 256, -1000, 2030, 1312, -1000, -1000, 2004, -1000, -1000, - -1000, -1000, -1000, 229, 224, 1680, 207, 1676, 207, -1000, - 55304, 910, 2167, 55304, -1000, -1000, -1000, 1108, 1108, -1000, - -1000, 2356, -1000, 1426, 2659, 24043, 24043, -1000, 902, -1000, - -1000, 448, -226, 2024, 2024, -1000, 2024, 2026, -1000, 2024, - 170, 2024, 162, 2024, -1000, -1000, 1576, 1576, -1000, 1575, - 2150, 1557, 2892, -1000, 1400, 21862, 2888, -1000, -1000, -263, - -263, -263, -263, -263, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -63, 2884, 2864, 2659, -1000, 2023, - 2020, 21862, 2659, 1576, 2129, 2659, 2659, 2659, 2659, 2659, - 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2125, 2109, 2100, - 2067, 2062, 2038, 2027, 2002, 1995, 1958, 1951, 1936, 1932, - 1928, 1913, 1863, 2659, 2659, 1819, 2659, 1815, 1799, -1000, - 1400, 1575, 2838, 1575, 2659, 2659, 2801, 295, 2659, 1712, - 1712, 1712, 1712, 1712, 1575, 1575, 1575, 1575, 2659, 53850, - -1000, -263, -1000, -1000, -366, -370, -1000, 1576, -263, 1897, - 24043, 2659, 24043, 24043, 24043, 2659, 1576, -1000, 1756, 1739, - 2796, 1728, 2659, 2781, 2659, 2659, 2659, 1665, -1000, 2484, - 1981, 2484, 1981, 2484, 1669, 1217, 55304, -1000, -1000, -1000, - -1000, 2555, 2541, -1000, 1887, -1000, 93, 615, -1000, 2303, - 2291, -1000, 2520, 2302, 2518, -1000, -1000, -1000, -1000, -1000, - 1400, -1000, 2383, 1905, -1000, 994, 1939, -1000, -1000, 20408, - 1694, 2265, 824, 1669, 1950, 2676, 2138, 2149, 3618, -1000, - -1000, -1000, -1000, 2191, -1000, 2160, -1000, -1000, 2000, -1000, - 2116, 352, 29859, 1930, 1930, -1000, 822, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1183, 8317, 2592, -1000, 1666, -1000, - 1395, 205, 1266, -1000, -1000, 991, 991, -1000, 1096, 1087, - -1000, 55304, 2018, -1000, 955, 1657, 955, 1260, -1000, -1000, - 1254, -1000, -1000, -1000, -1000, 2046, 2216, -1000, -1000, -1000, - -1000, 55304, -1000, -1000, 55304, 55304, 55304, 2013, 2512, -1000, - 21862, 2011, 992, 2701, 53850, 53850, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 432, 991, -491, - 292, 288, 991, 991, 991, -523, -1000, -1000, 1662, 1655, - -1000, -202, -1000, 21862, -1000, -1000, -1000, -1000, -1000, 1418, - 1418, 1651, 1647, 1607, -1000, 2000, -1000, -1000, -1000, 1800, - -1000, -1000, -181, 53850, 53850, 53850, 53850, -1000, -1000, -1000, - 1242, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 902, 1576, 399, -194, 1576, -1000, -1000, - 955, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 21862, -1000, 21862, -1000, 21862, 1400, 21862, -1000, -1000, - -1000, -1000, -1000, 2492, 1588, 21862, 21862, -1000, 1251, 1234, - 2659, -1000, -1000, -1000, 21862, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21862, -1000, - 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, - 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, - 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, 21862, -1000, - -1000, 21862, -1000, -1000, -1000, 21862, -1000, 21862, -1000, 21862, - -1000, -1000, -1000, 21862, 312, 1023, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1576, 350, -1000, - -1000, -1000, 2561, -1000, 1576, 21862, 1991, -1000, 1991, 1991, - 1991, -1000, -1000, -1000, 21862, -1000, 21862, 21862, -1000, 21862, - -1000, 21862, -1000, -1000, -1000, -1000, 21862, 1981, 2271, 38583, - 1981, 38583, 1981, 32040, -1000, -1000, 2541, 2546, 2511, 2279, - 2282, 2282, 2303, -1000, 2509, 2508, -1000, 1571, 2505, 1568, - 1086, -1000, 54577, 21862, -1000, 251, 37856, -1000, 393, 53850, - 251, 53850, -1000, 2540, -1000, -1000, 21862, 2010, -1000, 21862, - -1000, -1000, -1000, -1000, 5084, 2555, 1930, -1000, -1000, 918, - -1000, 21862, -1000, 10267, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 1564, 1554, -1000, -1000, 2006, 21862, -1000, -1000, - -1000, 1757, 1732, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 2000, -1000, -1000, -1000, -1000, 322, -515, 2687, 53850, - 1231, -1000, 1644, 1882, 289, 251, 1541, 991, 991, 991, - 1218, 1215, 37856, 1641, -1000, 53850, 411, -1000, 322, -1000, - -211, -212, 2659, -1000, -1000, 2437, -1000, -1000, 16034, -1000, - -1000, 1998, 2036, -1000, -1000, -1000, -1000, 2241, -171, -198, - -1000, -1000, 2659, 2659, 2659, 2032, 1576, -1000, 2659, 2659, - 1723, 1663, -1000, 2659, 2659, 2659, 2659, 2659, 2659, 2659, - 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, 2659, - 2659, 2659, 2659, 1575, 1650, -1000, 312, 1576, 2145, -1000, - -1000, 5084, -1000, -1000, 2540, 2504, 19, -1000, -1000, 237, - 19, 1400, 1028, 1576, 1576, 1028, 1646, 2659, 1635, 1631, - 2659, 2659, 32767, -1000, 2503, 2496, 1637, -1000, -1000, 38583, - 1637, 38583, 956, 2546, -270, 21862, 21862, 2275, 1238, -1000, - -1000, -1000, -1000, 1519, 1469, -1000, 1463, -1000, 2584, -1000, - 1400, -1000, 1981, 251, -1000, 811, 1939, -1000, 2492, 1400, - 53850, 1400, 90, 2540, -1000, 2659, -1000, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, 1981, - 1981, 1981, 1981, 1981, 1981, 1981, -1000, -1000, 53850, 2670, - -1000, -1000, 2436, 1639, 167, -1000, 1656, 1882, -1000, -1000, - 250, -1000, 21862, -1000, 37856, 1461, 1457, -1000, -1000, -1000, - -1000, -523, -1000, -1000, -1000, -1000, -1000, -1000, 378, 1817, - -1000, 974, 53850, 55304, -1000, 2229, -1000, -1000, -1000, -1000, - 21862, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 21885, -1000, 21885, -1000, 21885, 1182, 21885, -1000, -1000, -1000, + -1000, -1000, 2576, 1689, 21885, 21885, -1000, 1256, 1238, 1773, + -1000, -1000, -1000, 21885, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21885, -1000, 21885, + -1000, 21885, -1000, 21885, -1000, 21885, -1000, 21885, -1000, 21885, + -1000, 21885, -1000, 21885, -1000, 21885, -1000, 21885, -1000, 21885, + -1000, 21885, -1000, 21885, -1000, 21885, -1000, 21885, -1000, -1000, + 21885, -1000, -1000, -1000, 21885, -1000, 21885, -1000, 21885, -1000, + -1000, -1000, 21885, 227, 819, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 1625, 368, -1000, -1000, + -1000, 2693, -1000, 1625, 21885, 2197, -1000, 2197, 2197, 2197, + -1000, -1000, -1000, 21885, -1000, 21885, 21885, -1000, 21885, -1000, + 21885, -1000, -1000, -1000, -1000, 21885, 2081, 2437, 38675, 2081, + 38675, 2081, 32105, -1000, -1000, 2677, 2618, 2646, 2372, 2374, + 2374, 2376, -1000, 2645, 2621, -1000, 1688, 2606, 1630, 1019, + -1000, 54735, 21885, -1000, 249, 37945, -1000, 402, 54005, 249, + 54005, -1000, 2602, -1000, -1000, 21885, 2107, -1000, 21885, -1000, + -1000, -1000, -1000, 5149, 2679, 1998, -1000, -1000, 918, -1000, + 21885, -1000, 10275, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 1584, 1582, -1000, -1000, 2105, 21885, -1000, -1000, -1000, + 1746, 1728, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 2102, -1000, -1000, -1000, -1000, 356, -520, 2293, 54005, 1237, + -1000, 1680, 1980, 330, 249, 1540, 952, 952, 952, 1232, + 1220, 37945, 1676, -1000, 54005, 369, -1000, 356, -1000, -213, + -214, 1773, -1000, -1000, 2574, -1000, -1000, 16033, -1000, -1000, + 2094, 2198, -1000, -1000, -1000, -1000, 2322, -167, -196, -1000, + -1000, 1773, 1773, 1773, 1293, 1625, -1000, 1773, 1773, 1655, + 1648, -1000, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, + 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773, + 1773, 1773, 1616, 1781, -1000, 227, 1625, 2238, -1000, -1000, + 5149, -1000, -1000, 2602, 2604, 10, -1000, -1000, 246, 10, + 1182, 1007, 1625, 1625, 1007, 1756, 1773, 1751, 1739, 1773, + 1773, 32835, -1000, 2595, 2594, 1657, -1000, -1000, 38675, 1657, + 38675, 960, 2618, -294, 21885, 21885, 2365, 1254, -1000, -1000, + -1000, -1000, 1536, 1529, -1000, 1527, -1000, 2725, -1000, 1182, + -1000, 2081, 249, -1000, 532, 1820, -1000, 2576, 1182, 54005, + 1182, 83, 2602, -1000, 1773, -1000, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, 2081, + 2081, 2081, 2081, 2081, 2081, -1000, -1000, 54005, 2210, -1000, + -1000, 2563, 1665, 166, -1000, 1629, 1980, -1000, -1000, 209, + -1000, 21885, -1000, 37945, 1513, 1506, -1000, -1000, -1000, -1000, + -526, -1000, -1000, -1000, -1000, -1000, -1000, 408, 1976, -1000, + 944, 54005, 55465, -1000, 2267, -1000, -1000, -1000, -1000, 21885, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21862, -1000, - 1576, 2142, -1000, -364, -1000, -492, 21862, -263, -1000, -1000, - -263, -1000, -1000, -1000, -1000, -1000, 21862, -1000, -1000, 21862, - -1000, 21862, -1000, -1000, 1637, -1000, -1000, -1000, 37129, -1000, - 1637, -1000, 1637, -1000, -270, -1000, 1667, -1000, 53850, 1400, - 381, -1000, 1220, -1000, -1000, -1000, -1000, -1000, 54577, 53850, - 1939, 53850, -1000, -1000, 1618, 1576, 1981, 2492, -1000, 1586, - -1000, 378, -1000, 1994, 1968, -1000, -1000, -1000, 19681, -1000, - -1000, -1000, -1000, -1000, 283, -178, 16034, 11636, 1584, -1000, - -176, 2659, 1575, -1000, -467, -1000, -1000, -1000, -1000, 280, - -1000, -1000, 1652, -1000, -1000, 1624, 1620, 1605, -1000, -1000, - -1000, -1000, -1000, -1000, -270, -1000, -1000, 2431, -1000, -214, - -1000, -1000, 1648, 1559, -1000, -1000, -1000, 32040, 53123, -1000, - -165, 316, -178, 21862, 1987, 1576, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -38, -1000, -1000, 798, -1000, -1000, - -1000, 2004, -196, -1000, -1000, -1000, 301, -482, -283, -284, - 24043, -1000, 21862, -1000, 21862, -1000, 21862, -1000, 53850, 1981, - -1000, -1000, -1000, 1547, -1000, 3891, -381, 2130, -1000, -136, - -1000, -1000, -1000, 1112, 1428, -1000, -1000, -1000, -1000, -1000, - -1000, 2664, 53850, -1000, 426, -1000, -1000, 15301, -181, -200, - 1064, -1000, -1000, -1000, -1000, -1000, 1991, 1516, 1229, 2659, - -1000, 53850, -1000, 53123, -375, 901, 5084, -1000, 2118, 2110, - 2560, -1000, -1000, -1000, -1000, -1000, -1000, -529, 1490, 265, - -1000, -1000, -1000, 301, -293, -1000, 21862, -1000, 21862, -1000, - 1576, -1000, -1000, 2389, 90, -1000, 2582, -1000, 2572, 1030, - 1030, -1000, 1209, -529, -1000, -1000, -1000, -1000, 2659, 2659, - -1000, -388, -1000, -1000, -1000, -1000, -1000, 423, 1267, -1000, - -1000, -1000, -1000, -1000, 5084, -1000, -1000, -1000, 231, 231, - -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21885, -1000, 1625, + 2236, -1000, -363, -1000, -493, 21885, -269, -1000, -1000, -269, + -1000, -1000, -1000, -1000, -1000, 21885, -1000, -1000, 21885, -1000, + 21885, -1000, -1000, 1657, -1000, -1000, -1000, 37215, -1000, 1657, + -1000, 1657, -1000, -294, -1000, 1974, -1000, 54005, 1182, 315, + -1000, 1196, -1000, -1000, -1000, -1000, -1000, 54735, 54005, 1820, + 54005, -1000, -1000, 1654, 1625, 2081, 2576, -1000, 1624, -1000, + 408, -1000, 2093, 2172, -1000, -1000, -1000, 19695, -1000, -1000, + -1000, -1000, -1000, 272, -175, 16033, 11617, 1619, -1000, -170, + 1773, 1616, -1000, -469, -1000, -1000, -1000, -1000, 297, -1000, + -1000, 1967, -1000, -1000, 1723, 1647, 1633, -1000, -1000, -1000, + -1000, -1000, -1000, -294, -1000, -1000, 2544, -1000, -235, -1000, + -1000, 1711, 1580, -1000, -1000, -1000, 32105, 53275, -1000, -161, + 353, -175, 21885, 2086, 1625, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -43, -1000, -1000, 518, -1000, -1000, -1000, + 2196, -194, -1000, -1000, -1000, 300, -483, -271, -272, 24075, + -1000, 21885, -1000, 21885, -1000, 21885, -1000, 54005, 2081, -1000, + -1000, -1000, 1578, -1000, 3903, -386, 2235, -1000, -139, -1000, + -1000, -1000, 1153, 1499, -1000, -1000, -1000, -1000, -1000, -1000, + 2052, 54005, -1000, 449, -1000, -1000, 15297, -179, -198, 1008, + -1000, -1000, -1000, -1000, -1000, 2197, 1614, 1606, 1773, -1000, + 54005, -1000, 53275, -381, 901, 5149, -1000, 2232, 2220, 2683, + -1000, -1000, -1000, -1000, -1000, -1000, -535, 1489, 286, -1000, + -1000, -1000, 300, -283, -1000, 21885, -1000, 21885, -1000, 1625, + -1000, -1000, 2533, 83, -1000, 2714, -1000, 2708, 1069, 1069, + -1000, 1215, -535, -1000, -1000, -1000, -1000, 1773, 1773, -1000, + -388, -1000, -1000, -1000, -1000, -1000, 441, 1265, -1000, -1000, + -1000, -1000, -1000, 5149, -1000, -1000, -1000, 230, 230, -1000, + -1000, } var yyPgo = [...]int{ - 0, 3204, 3202, 31, 6, 45, 44, 3201, 3200, 3198, - 172, 3184, 3183, 3180, 3175, 3174, 3172, 2630, 2619, 2608, - 3169, 3168, 3160, 3159, 3158, 3157, 3156, 3155, 3152, 43, - 95, 25, 106, 215, 193, 3151, 171, 163, 197, 3150, - 3149, 3146, 118, 189, 83, 85, 190, 3144, 3140, 75, - 3139, 3136, 3135, 188, 187, 186, 1089, 3134, 179, 115, - 50, 3132, 3131, 3130, 3129, 3128, 3127, 3124, 3120, 3119, - 3118, 3115, 3111, 3107, 3105, 3102, 3095, 3094, 3093, 278, - 3090, 3089, 21, 3087, 77, 3085, 3076, 3075, 3072, 3070, - 11, 3069, 3067, 26, 42, 66, 3065, 3064, 51, 3063, - 3062, 3060, 3056, 3054, 71, 3050, 22, 3044, 37, 3040, - 3039, 127, 3038, 3035, 3025, 38, 3023, 3019, 3015, 30, - 168, 3011, 3010, 140, 3005, 3004, 3003, 169, 224, 3002, - 2248, 3001, 97, 3000, 2999, 2998, 165, 191, 2995, 121, - 2994, 2993, 2992, 151, 2988, 3254, 2986, 2985, 68, 73, - 201, 2984, 2979, 199, 72, 8, 2978, 17, 18, 2974, - 2970, 65, 70, 2969, 114, 2966, 2965, 101, 87, 2957, - 109, 98, 2948, 2947, 5, 7, 2937, 1, 4, 2, - 104, 2934, 2931, 103, 2928, 2924, 2921, 93, 2914, 2909, - 3875, 2904, 91, 130, 108, 63, 2903, 166, 175, 2902, - 2898, 2895, 2894, 2893, 53, 2889, 2883, 2876, 138, 1275, - 123, 2873, 146, 352, 54, 147, 2871, 196, 78, 198, - 167, 2869, 2866, 136, 134, 2865, 2859, 57, 164, 192, - 2858, 94, 131, 120, 181, 92, 141, 2857, 2851, 58, - 60, 2848, 2844, 2841, 2834, 170, 2833, 2830, 64, 2827, - 56, 2826, 202, 2824, 335, 80, 2823, 182, 162, 2820, - 67, 2818, 2817, 90, 100, 62, 36, 2816, 156, 159, - 128, 185, 2813, 2810, 55, 2802, 2798, 2797, 195, 306, - 2796, 2795, 316, 173, 144, 148, 84, 2793, 263, 2792, - 2787, 14, 4355, 6376, 177, 40, 160, 2784, 2781, 7734, - 16, 47, 29, 2775, 205, 2769, 180, 2768, 2762, 2757, - 242, 203, 112, 157, 59, 2755, 2753, 2752, 2743, 35, - 2742, 2739, 2737, 2736, 2735, 2732, 41, 39, 34, 74, - 213, 61, 20, 96, 158, 153, 69, 2731, 2730, 2729, - 125, 82, 2720, 155, 154, 126, 99, 2715, 176, 143, - 117, 2713, 105, 33, 2712, 2709, 2708, 2706, 89, 2702, - 2688, 2682, 2680, 152, 145, 124, 79, 2675, 81, 119, - 150, 149, 52, 2673, 48, 2670, 2658, 32, 178, 27, - 2656, 19, 102, 110, 2655, 6223, 2654, 9, 262, 161, - 2653, 2652, 10, 13, 12, 2650, 2649, 2645, 2643, 133, - 2641, 2640, 2639, 2637, 24, 49, 23, 15, 116, 139, - 76, 2636, 2621, 142, 2620, 2613, 2612, 0, 1031, 129, - 2576, 200, + 0, 3389, 3388, 25, 9, 41, 38, 3387, 3385, 3382, + 174, 3380, 3379, 3377, 3376, 3375, 3374, 2765, 2758, 2757, + 3373, 3367, 3363, 3362, 3357, 3355, 3354, 3353, 3346, 50, + 103, 81, 101, 212, 204, 3344, 172, 157, 198, 3343, + 3336, 3320, 113, 186, 80, 82, 194, 3318, 3313, 69, + 3245, 3242, 3238, 183, 181, 180, 1047, 3237, 178, 112, + 45, 3236, 3227, 3224, 3223, 3222, 3220, 3216, 3215, 3214, + 3213, 3211, 3210, 3209, 3208, 3207, 3194, 3193, 3192, 278, + 3189, 3185, 21, 3184, 73, 3183, 3181, 3180, 3179, 3173, + 6, 3172, 3169, 26, 34, 65, 3165, 3163, 44, 3161, + 3160, 3159, 3158, 3153, 76, 3145, 13, 3144, 33, 3143, + 3140, 124, 3138, 3137, 3133, 40, 3132, 3131, 3127, 14, + 165, 3125, 3120, 139, 3119, 3118, 3117, 163, 219, 3116, + 2348, 3114, 97, 3113, 3112, 3110, 162, 195, 3109, 119, + 3103, 3102, 3100, 145, 3099, 3301, 3098, 3097, 72, 63, + 201, 3096, 3095, 199, 77, 5, 3091, 19, 20, 3089, + 3088, 74, 67, 3082, 104, 3081, 3078, 100, 91, 3076, + 96, 90, 3075, 3074, 8, 10, 3071, 1, 4, 2, + 108, 3062, 3054, 114, 3052, 3051, 3049, 98, 3048, 3046, + 7060, 3044, 83, 132, 99, 68, 3041, 166, 125, 3039, + 3038, 3033, 3026, 3025, 3020, 49, 3019, 3018, 3017, 136, + 1264, 109, 3016, 149, 362, 51, 147, 3015, 190, 75, + 197, 170, 3012, 3011, 134, 129, 3009, 3008, 59, 164, + 192, 3007, 94, 128, 117, 179, 92, 130, 3006, 3003, + 56, 60, 3002, 3001, 2999, 2992, 171, 2990, 2983, 64, + 2982, 54, 2981, 168, 2977, 339, 55, 2971, 182, 156, + 2966, 62, 2964, 2951, 87, 95, 58, 30, 2950, 155, + 159, 126, 184, 2949, 2947, 52, 2941, 2940, 2937, 196, + 319, 2931, 2921, 250, 176, 142, 146, 85, 2917, 337, + 2906, 2905, 16, 4449, 6490, 185, 37, 161, 2904, 2901, + 7709, 46, 42, 24, 2900, 205, 2892, 187, 2889, 2887, + 2886, 226, 206, 110, 158, 57, 2882, 2880, 2872, 2871, + 39, 2870, 2867, 2848, 2847, 2846, 2844, 36, 35, 32, + 71, 215, 61, 27, 131, 152, 151, 66, 2840, 2839, + 2836, 121, 93, 2833, 154, 153, 123, 102, 2832, 177, + 141, 118, 2830, 105, 31, 2823, 2822, 2821, 2820, 89, + 2819, 2814, 2811, 2810, 150, 143, 120, 78, 2809, 79, + 116, 148, 144, 48, 2802, 43, 2793, 2792, 29, 193, + 28, 2790, 18, 106, 115, 2789, 6331, 2788, 12, 328, + 160, 2787, 2784, 7, 15, 22, 2781, 2779, 2778, 2775, + 133, 2774, 2772, 2770, 2769, 23, 47, 11, 17, 111, + 138, 70, 2766, 2764, 140, 2759, 2753, 2747, 0, 1034, + 127, 2745, 200, } -//line sql.y:8655 +//line sql.y:8680 type yySymType struct { union any empty struct{} @@ -8445,59 +8468,59 @@ func (st *yySymType) withUnion() *With { } var yyR1 = [...]int{ - 0, 415, 416, 416, 7, 7, 7, 7, 7, 7, + 0, 416, 417, 417, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 260, 385, 258, 258, 28, 74, 36, 36, 35, + 7, 261, 386, 259, 259, 28, 74, 36, 36, 35, 35, 38, 38, 37, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 29, 29, 29, 29, 30, 30, 30, 30, 30, 15, 16, 34, 34, 17, 17, 109, 109, 18, 19, 19, - 19, 19, 419, 419, 185, 185, 183, 183, 184, 184, - 263, 263, 20, 267, 267, 269, 269, 269, 269, 259, - 259, 259, 21, 21, 268, 268, 270, 270, 270, 273, - 273, 273, 273, 313, 313, 313, 22, 22, 22, 22, - 22, 129, 129, 387, 387, 386, 381, 381, 380, 380, - 379, 384, 384, 383, 383, 382, 40, 41, 50, 50, - 50, 50, 51, 52, 388, 388, 354, 57, 57, 56, + 19, 19, 420, 420, 185, 185, 183, 183, 184, 184, + 264, 264, 20, 268, 268, 270, 270, 270, 270, 260, + 260, 260, 21, 21, 269, 269, 271, 271, 271, 274, + 274, 274, 274, 314, 314, 314, 22, 22, 22, 22, + 22, 129, 129, 388, 388, 387, 382, 382, 381, 381, + 380, 385, 385, 384, 384, 383, 40, 41, 50, 50, + 50, 50, 51, 52, 389, 389, 355, 57, 57, 56, 56, 56, 56, 56, 56, 58, 58, 54, 54, 53, - 53, 55, 55, 356, 356, 342, 342, 355, 355, 355, - 355, 355, 355, 355, 341, 341, 140, 140, 237, 237, - 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, - 237, 237, 237, 237, 237, 403, 403, 403, 402, 402, - 238, 238, 238, 238, 238, 238, 238, 238, 149, 149, + 53, 55, 55, 357, 357, 343, 343, 356, 356, 356, + 356, 356, 356, 356, 342, 342, 140, 140, 238, 238, + 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, + 238, 238, 238, 238, 238, 404, 404, 404, 403, 403, + 239, 239, 239, 239, 239, 239, 239, 239, 149, 149, 161, 161, 161, 161, 161, 161, 147, 147, 148, 146, 146, 146, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 407, - 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, - 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, - 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, - 407, 407, 407, 407, 407, 407, 407, 407, 407, 407, - 407, 160, 160, 155, 155, 155, 157, 157, 156, 156, - 156, 158, 158, 404, 404, 404, 404, 319, 319, 319, - 319, 322, 322, 320, 320, 320, 320, 320, 320, 320, - 320, 320, 321, 321, 321, 321, 321, 321, 321, 323, - 323, 323, 323, 323, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 325, 325, 325, 325, 325, 325, 325, 325, 340, 340, - 329, 329, 334, 334, 335, 335, 336, 336, 336, 337, - 337, 337, 338, 338, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 333, 333, 332, 332, 332, 343, 368, - 368, 367, 367, 365, 365, 365, 365, 365, 365, 365, - 365, 352, 352, 362, 362, 362, 362, 362, 351, 351, - 347, 347, 347, 348, 348, 349, 349, 346, 346, 350, - 350, 364, 364, 363, 363, 344, 344, 345, 345, 370, - 405, 405, 405, 405, 405, 406, 406, 371, 395, 397, - 397, 397, 396, 396, 393, 394, 392, 392, 392, 392, - 392, 84, 84, 84, 286, 286, 287, 287, 360, 360, - 359, 359, 359, 361, 361, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 281, 281, 281, 391, - 391, 391, 391, 391, 391, 390, 390, 390, 357, 357, - 357, 357, 389, 389, 59, 59, 218, 218, 408, 408, - 410, 410, 410, 47, 47, 47, 47, 47, 47, 46, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 408, + 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, + 408, 160, 160, 155, 155, 155, 157, 157, 156, 156, + 156, 158, 158, 405, 405, 405, 405, 320, 320, 320, + 320, 323, 323, 321, 321, 321, 321, 321, 321, 321, + 321, 321, 322, 322, 322, 322, 322, 322, 322, 324, + 324, 324, 324, 324, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 326, 326, 326, 326, 326, 326, 326, 326, 341, 341, + 330, 330, 335, 335, 336, 336, 337, 337, 337, 338, + 338, 338, 339, 339, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 334, 334, 333, 333, 333, 344, 369, + 369, 368, 368, 366, 366, 366, 366, 366, 366, 366, + 366, 353, 353, 363, 363, 363, 363, 363, 352, 352, + 348, 348, 348, 349, 349, 350, 350, 347, 347, 351, + 351, 365, 365, 364, 364, 345, 345, 346, 346, 371, + 406, 406, 406, 406, 406, 407, 407, 372, 396, 398, + 398, 398, 397, 397, 394, 395, 393, 393, 393, 393, + 393, 84, 84, 84, 287, 287, 288, 288, 361, 361, + 360, 360, 360, 362, 362, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 282, 282, 282, 392, + 392, 392, 392, 392, 392, 391, 391, 391, 358, 358, + 358, 358, 390, 390, 59, 59, 219, 219, 409, 409, + 411, 411, 411, 47, 47, 47, 47, 47, 47, 46, 46, 46, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, @@ -8506,126 +8529,109 @@ var yyR1 = [...]int{ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 111, 111, 112, - 112, 112, 112, 114, 114, 114, 373, 373, 60, 60, + 112, 112, 112, 114, 114, 114, 374, 374, 60, 60, 3, 3, 173, 175, 176, 176, 174, 174, 174, 174, 174, 174, 62, 62, 61, 61, 178, 177, 179, 179, - 179, 1, 1, 2, 2, 4, 4, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 339, - 339, 339, 372, 372, 374, 113, 113, 113, 113, 113, + 179, 1, 1, 2, 2, 4, 4, 379, 379, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 379, 340, + 340, 340, 373, 373, 375, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 117, 116, 116, 115, 118, - 118, 118, 118, 118, 118, 118, 118, 376, 376, 376, - 63, 63, 377, 326, 327, 328, 5, 6, 353, 375, + 118, 118, 118, 118, 118, 118, 118, 377, 377, 377, + 63, 63, 378, 327, 328, 329, 5, 6, 354, 376, 125, 125, 24, 39, 39, 25, 25, 25, 25, 26, 26, 64, 67, 67, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 280, 280, 289, - 289, 279, 279, 304, 304, 304, 282, 282, 282, 283, - 283, 401, 401, 401, 276, 276, 66, 66, 66, 305, - 305, 305, 305, 69, 69, 411, 411, 412, 412, 413, - 413, 413, 70, 71, 71, 308, 308, 309, 309, 72, + 65, 65, 65, 65, 65, 65, 65, 281, 281, 290, + 290, 280, 280, 305, 305, 305, 283, 283, 283, 284, + 284, 402, 402, 402, 277, 277, 66, 66, 66, 306, + 306, 306, 306, 69, 69, 412, 412, 413, 413, 414, + 414, 414, 70, 71, 71, 309, 309, 310, 310, 72, 73, 85, 85, 85, 85, 85, 86, 86, 86, 86, 110, 110, 110, 10, 10, 10, 10, 81, 81, 81, - 9, 9, 11, 68, 68, 75, 398, 398, 399, 400, - 400, 400, 400, 76, 78, 27, 27, 27, 27, 27, + 9, 9, 11, 68, 68, 75, 399, 399, 400, 401, + 401, 401, 401, 76, 78, 27, 27, 27, 27, 27, 27, 135, 135, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 130, 130, 130, 124, 124, - 420, 79, 80, 80, 128, 128, 128, 121, 121, 121, - 127, 127, 127, 12, 12, 13, 262, 262, 14, 14, + 421, 79, 80, 80, 128, 128, 128, 121, 121, 121, + 127, 127, 127, 12, 12, 13, 263, 263, 14, 14, 134, 134, 133, 133, 136, 136, 136, 136, 136, 136, - 136, 131, 131, 132, 132, 132, 132, 297, 297, 297, - 296, 296, 167, 167, 169, 168, 168, 170, 170, 171, - 171, 171, 171, 216, 216, 193, 193, 255, 255, 256, - 256, 254, 254, 261, 261, 257, 257, 257, 257, 264, - 264, 172, 172, 172, 172, 180, 180, 181, 181, 182, - 182, 307, 307, 302, 302, 302, 301, 301, 186, 186, + 136, 131, 131, 132, 132, 132, 132, 298, 298, 298, + 297, 297, 167, 167, 169, 168, 168, 170, 170, 171, + 171, 171, 171, 217, 217, 193, 193, 256, 256, 257, + 257, 255, 255, 262, 262, 258, 258, 258, 258, 265, + 265, 172, 172, 172, 172, 180, 180, 181, 181, 182, + 182, 308, 308, 303, 303, 303, 302, 302, 186, 186, 186, 188, 187, 187, 187, 187, 189, 189, 191, 191, 190, 190, 192, 197, 197, 196, 196, 194, 194, 194, 194, 194, 194, 195, 195, 195, 195, 198, 198, 145, - 145, 145, 145, 145, 145, 145, 145, 409, 409, 159, - 159, 159, 159, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 245, 245, 150, 150, 150, 150, + 145, 145, 145, 145, 145, 145, 145, 410, 410, 159, + 159, 159, 159, 159, 159, 159, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 246, 246, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 150, 150, 150, 150, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 221, 221, 220, 220, - 87, 87, 87, 88, 88, 89, 89, 89, 89, 89, - 90, 90, 90, 90, 90, 90, 90, 92, 92, 91, - 91, 211, 211, 294, 294, 93, 94, 94, 95, 95, - 98, 98, 97, 96, 96, 102, 102, 99, 99, 101, - 101, 100, 103, 103, 104, 105, 105, 277, 277, 199, - 199, 207, 207, 207, 207, 200, 200, 200, 200, 200, - 200, 200, 208, 208, 208, 215, 209, 209, 205, 205, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 164, 164, 164, 164, 226, 226, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 152, 152, 165, 165, 165, 165, 166, - 166, 166, 166, 166, 166, 166, 315, 315, 119, 119, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 222, + 222, 221, 221, 87, 87, 87, 88, 88, 89, 89, + 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, + 92, 92, 91, 91, 212, 212, 295, 295, 93, 94, + 94, 95, 95, 98, 98, 97, 96, 96, 102, 102, + 99, 99, 101, 101, 100, 103, 103, 104, 105, 105, + 278, 278, 199, 199, 208, 208, 208, 208, 200, 200, + 201, 201, 201, 201, 201, 201, 209, 209, 209, 216, + 210, 210, 206, 206, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 164, 164, 164, 164, + 227, 227, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 152, 152, 165, + 165, 165, 165, 166, 166, 166, 166, 166, 166, 166, + 316, 316, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, 120, 120, + 119, 119, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 421, 421, 330, 330, - 330, 206, 206, 206, 206, 206, 126, 126, 126, 126, - 126, 312, 312, 312, 316, 316, 316, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 317, 317, 224, 224, 122, 122, 222, 222, - 223, 225, 225, 217, 217, 217, 217, 219, 219, 202, - 202, 202, 227, 227, 318, 318, 228, 228, 106, 107, - 107, 108, 108, 229, 229, 231, 230, 230, 232, 233, - 233, 233, 234, 234, 235, 235, 235, 49, 49, 49, - 49, 49, 44, 44, 44, 44, 45, 45, 45, 45, - 137, 137, 137, 137, 139, 139, 138, 138, 82, 82, - 83, 83, 83, 143, 143, 144, 144, 144, 141, 141, - 142, 142, 252, 252, 252, 252, 252, 252, 252, 236, - 236, 236, 243, 243, 243, 239, 239, 241, 241, 241, - 242, 242, 242, 240, 249, 249, 251, 251, 250, 250, - 246, 246, 247, 247, 248, 248, 248, 244, 244, 201, - 201, 201, 201, 201, 253, 253, 253, 253, 306, 306, - 306, 265, 265, 212, 212, 214, 214, 213, 213, 163, - 266, 266, 274, 271, 271, 272, 272, 298, 298, 298, - 275, 275, 288, 288, 284, 284, 285, 285, 278, 278, - 290, 290, 290, 77, 210, 210, 369, 369, 366, 293, - 293, 295, 295, 299, 299, 303, 303, 300, 300, 8, - 414, 414, 414, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, + 422, 422, 331, 331, 331, 207, 207, 207, 207, 207, + 126, 126, 126, 126, 126, 313, 313, 313, 317, 317, + 317, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 318, 318, 225, 225, + 122, 122, 223, 223, 224, 226, 226, 218, 218, 218, + 218, 220, 220, 203, 203, 203, 228, 228, 319, 319, + 229, 229, 106, 107, 107, 108, 108, 230, 230, 232, + 231, 231, 233, 234, 234, 234, 235, 235, 236, 236, + 236, 49, 49, 49, 49, 49, 44, 44, 44, 44, + 45, 45, 45, 45, 137, 137, 137, 137, 139, 139, + 138, 138, 82, 82, 83, 83, 83, 143, 143, 144, + 144, 144, 141, 141, 142, 142, 253, 253, 253, 253, + 253, 253, 253, 237, 237, 237, 244, 244, 244, 240, + 240, 242, 242, 242, 243, 243, 243, 241, 250, 250, + 252, 252, 251, 251, 247, 247, 248, 248, 249, 249, + 249, 245, 245, 202, 202, 202, 202, 202, 254, 254, + 254, 254, 307, 307, 307, 266, 266, 213, 213, 215, + 215, 214, 214, 163, 267, 267, 275, 272, 272, 273, + 273, 299, 299, 299, 276, 276, 289, 289, 285, 285, + 286, 286, 279, 279, 291, 291, 291, 77, 211, 211, + 370, 370, 367, 294, 294, 296, 296, 300, 300, 304, + 304, 301, 301, 8, 415, 415, 415, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, @@ -8640,37 +8646,55 @@ var yyR1 = [...]int{ 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 417, 418, 310, 311, 311, 311, + 292, 292, 292, 292, 292, 292, 292, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 418, 419, 311, + 312, 312, 312, } var yyR2 = [...]int{ @@ -8775,69 +8799,69 @@ var yyR2 = [...]int{ 1, 3, 3, 0, 1, 1, 2, 6, 5, 6, 6, 5, 5, 0, 2, 3, 3, 0, 2, 3, 3, 3, 2, 3, 1, 3, 6, 1, 1, 3, - 4, 3, 1, 3, 4, 5, 6, 3, 4, 5, - 6, 3, 4, 1, 1, 1, 3, 3, 3, 3, - 3, 3, 5, 5, 3, 3, 3, 3, 3, 3, - 1, 1, 1, 1, 1, 3, 1, 1, 1, 2, - 2, 2, 2, 1, 1, 2, 7, 7, 6, 6, - 2, 2, 5, 6, 3, 3, 1, 3, 1, 3, + 4, 3, 4, 4, 4, 1, 3, 4, 5, 6, + 3, 4, 5, 6, 3, 4, 1, 1, 1, 3, + 3, 3, 3, 3, 3, 5, 5, 3, 3, 3, + 3, 3, 3, 1, 1, 1, 1, 1, 3, 1, + 1, 1, 2, 2, 2, 2, 1, 1, 2, 7, + 7, 6, 6, 2, 2, 5, 6, 3, 3, 1, + 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 4, 2, 4, + 0, 1, 2, 5, 0, 3, 0, 1, 4, 4, + 2, 1, 0, 0, 1, 1, 2, 2, 1, 1, + 2, 2, 0, 1, 1, 1, 1, 5, 1, 3, + 0, 3, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 4, 2, 4, 0, 1, 2, - 5, 0, 3, 0, 1, 4, 4, 2, 1, 0, - 0, 1, 1, 2, 2, 1, 1, 2, 2, 0, - 1, 1, 1, 1, 5, 1, 3, 0, 3, 1, - 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 4, 6, - 4, 4, 8, 8, 6, 8, 6, 5, 4, 10, - 2, 2, 1, 2, 2, 2, 2, 2, 5, 6, - 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 8, 4, 8, 8, 6, 5, - 4, 4, 4, 4, 4, 7, 4, 4, 6, 6, - 6, 8, 6, 6, 4, 4, 3, 4, 6, 6, - 4, 4, 6, 4, 6, 4, 4, 4, 4, 4, - 4, 6, 4, 6, 4, 4, 4, 6, 4, 6, - 4, 4, 6, 4, 6, 4, 6, 8, 4, 6, + 1, 3, 4, 6, 4, 4, 8, 8, 6, 8, + 6, 5, 4, 10, 2, 2, 1, 2, 2, 2, + 2, 2, 5, 6, 6, 6, 6, 6, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 8, 4, + 8, 8, 6, 5, 4, 4, 4, 4, 4, 7, + 4, 4, 6, 6, 6, 8, 6, 6, 4, 4, + 3, 4, 6, 6, 4, 4, 6, 4, 6, 4, + 4, 4, 4, 4, 4, 6, 4, 6, 4, 4, + 4, 6, 4, 6, 4, 4, 6, 4, 6, 4, + 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, - 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, - 4, 6, 8, 4, 4, 4, 6, 4, 6, 4, - 8, 6, 4, 4, 6, 4, 6, 8, 4, 6, - 8, 4, 4, 6, 8, 6, 4, 6, 6, 8, - 10, 7, 8, 8, 9, 4, 4, 4, 4, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, - 4, 4, 4, 4, 4, 6, 4, 6, 5, 9, - 6, 9, 8, 6, 8, 8, 8, 6, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 2, 6, 8, - 10, 12, 14, 6, 8, 8, 10, 12, 14, 6, - 8, 10, 12, 6, 8, 4, 4, 3, 4, 6, - 6, 4, 6, 4, 6, 8, 0, 2, 1, 1, + 8, 4, 6, 8, 4, 6, 8, 4, 4, 4, + 6, 4, 6, 4, 8, 6, 4, 4, 6, 4, + 6, 8, 4, 6, 8, 4, 4, 6, 8, 6, + 4, 6, 6, 8, 10, 7, 8, 8, 9, 4, + 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 4, 4, 4, 4, 4, 4, 6, + 4, 6, 5, 9, 6, 9, 8, 6, 8, 8, + 8, 6, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 2, 6, 8, 10, 12, 14, 6, 8, 8, + 10, 12, 14, 6, 8, 10, 12, 6, 8, 4, + 4, 3, 4, 6, 6, 4, 6, 4, 6, 8, + 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 2, 0, 2, - 3, 4, 4, 4, 4, 4, 0, 3, 4, 7, - 3, 1, 1, 1, 0, 5, 5, 2, 3, 1, - 2, 2, 1, 2, 1, 2, 2, 1, 2, 2, - 1, 1, 0, 1, 0, 1, 0, 2, 1, 2, - 4, 0, 2, 1, 1, 3, 5, 1, 1, 1, - 2, 2, 0, 4, 0, 2, 0, 2, 2, 1, - 3, 0, 1, 0, 1, 3, 1, 3, 2, 0, - 1, 1, 0, 1, 2, 4, 4, 0, 2, 2, - 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, - 0, 3, 3, 3, 0, 3, 1, 1, 0, 4, - 0, 1, 1, 0, 3, 1, 3, 2, 1, 1, - 0, 1, 2, 3, 4, 2, 3, 4, 4, 9, - 3, 5, 0, 3, 3, 0, 1, 0, 2, 2, - 0, 2, 2, 2, 0, 2, 1, 2, 3, 3, - 0, 2, 1, 2, 3, 4, 3, 0, 1, 3, - 1, 6, 5, 4, 1, 3, 3, 5, 0, 2, - 5, 0, 5, 1, 3, 1, 2, 3, 4, 1, - 1, 3, 3, 1, 2, 1, 1, 1, 1, 1, - 1, 1, 0, 1, 0, 2, 0, 3, 0, 1, - 0, 1, 1, 5, 0, 1, 0, 1, 2, 1, - 1, 1, 1, 1, 1, 0, 1, 1, 1, 3, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 2, 0, 2, 3, 4, 4, 4, 4, 4, + 0, 3, 4, 7, 3, 1, 1, 1, 0, 5, + 5, 2, 3, 1, 2, 2, 1, 2, 1, 2, + 2, 1, 2, 2, 1, 1, 0, 1, 0, 1, + 0, 2, 1, 2, 4, 0, 2, 1, 1, 3, + 5, 1, 1, 1, 2, 2, 0, 4, 0, 2, + 0, 2, 2, 1, 3, 0, 1, 0, 1, 3, + 1, 3, 2, 0, 1, 1, 0, 1, 2, 4, + 4, 0, 2, 2, 1, 1, 3, 3, 3, 3, + 3, 3, 3, 3, 0, 3, 3, 3, 0, 3, + 1, 1, 0, 4, 0, 1, 1, 0, 3, 1, + 3, 2, 1, 1, 0, 1, 2, 3, 4, 2, + 3, 4, 4, 9, 3, 5, 0, 3, 3, 0, + 1, 0, 2, 2, 0, 2, 2, 2, 0, 2, + 1, 2, 3, 3, 0, 2, 1, 2, 3, 4, + 3, 0, 1, 3, 1, 6, 5, 4, 1, 3, + 3, 5, 0, 2, 5, 0, 5, 1, 3, 1, + 2, 3, 4, 1, 1, 3, 3, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 0, 2, + 0, 3, 0, 1, 0, 1, 1, 5, 0, 1, + 0, 1, 2, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -8899,430 +8923,432 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, } var yyChk = [...]int{ - -1000, -415, -79, -420, -7, -29, -15, -16, -17, -18, + -1000, -416, -79, -421, -7, -29, -15, -16, -17, -18, -19, -20, -21, -22, -23, -24, -25, -26, -64, -67, -65, -66, -69, -70, -71, -72, -73, -9, -11, -68, -27, -28, -74, -75, -76, -77, -78, -12, -13, -14, - -8, -32, -31, -30, 11, 12, -109, -35, 34, -40, - -50, 229, -51, -41, 230, -52, 232, 231, 269, 233, - 382, 262, 76, 318, 319, 321, 322, 323, 324, -110, - 689, 267, 268, 235, 38, 47, 35, 36, 39, 239, - 275, 276, 238, 135, -33, -36, 10, -417, 13, 472, - 264, 263, 30, -34, 582, 88, -80, -416, 737, -252, - -236, 24, 35, 31, -235, -231, -128, -236, 22, 20, - 9, -79, -79, -79, 14, 15, -79, -354, -356, 88, - 162, 88, -79, -57, -56, -54, -53, -55, -58, 33, - -47, -48, -378, -46, -43, 234, 231, 279, 125, 126, - 269, 270, 271, 233, 253, 268, 272, 267, 288, -42, - 83, 35, 582, 585, -361, 230, 236, 237, 232, 473, - 128, 127, 77, -358, 377, 616, 707, -58, 709, 102, - 105, 708, 46, 243, 710, 711, 712, 623, 713, 252, - 714, 715, 716, 717, 723, 664, 724, 725, 726, 129, - 9, -79, -303, -299, 92, -292, 579, 255, 614, 426, - 615, 304, 83, 43, 518, 589, 374, 377, 616, 503, - 707, 383, 318, 334, 328, 508, 509, 510, 357, 349, - 580, 617, 590, 307, 256, 292, 701, 347, 138, 709, - 311, 618, 270, 384, 385, 619, 386, 102, 321, 423, - 722, 310, 620, 720, 105, 708, 326, 81, 502, 53, - 704, 46, 265, 431, 432, 345, 238, 341, 710, 293, - 621, 592, 286, 128, 125, 729, 38, 337, 52, 32, - 719, 127, 51, 711, 153, 622, 712, 623, 388, 364, - 695, 50, 389, 271, 624, 86, 276, 584, 315, 703, - 390, 523, 338, 391, 303, 718, 235, 625, 314, 684, - 676, 677, 392, 393, 696, 369, 365, 370, 525, 626, - 415, 507, 394, 680, 681, 736, 54, 627, 628, 697, - 126, 629, 80, 713, 82, 332, 333, 630, 301, 254, - 528, 529, 417, 361, 485, 492, 493, 112, 113, 488, - 114, 494, 115, 495, 496, 497, 486, 116, 109, 487, - 498, 499, 362, 363, 117, 500, 111, 110, 489, 491, - 118, 501, 252, 37, 395, 581, 305, 60, 309, 280, - 418, 48, 367, 733, 47, 691, 530, 631, 694, 360, - 356, 482, 55, 632, 633, 634, 635, 504, 714, 359, - 331, 355, 728, 4, 298, 477, 505, 715, 64, 237, - 372, 371, 373, 287, 414, 352, 636, 637, 638, 259, - 84, 639, 342, 23, 640, 641, 396, 294, 642, 58, - 643, 644, 421, 268, 645, 56, 716, 41, 646, 273, - 730, 717, 647, 648, 649, 690, 650, 275, 651, 398, - 652, 678, 679, 397, 366, 368, 531, 282, 399, 382, - 240, 583, 653, 316, 336, 272, 721, 654, 260, 519, - 520, 521, 522, 702, 527, 526, 274, 279, 267, 422, - 261, 655, 656, 657, 658, 659, 308, 675, 660, 661, - 322, 587, 723, 483, 45, 662, 663, 664, 665, 666, - 302, 297, 416, 425, 63, 85, 379, 667, 668, 700, - 330, 327, 295, 463, 465, 466, 467, 468, 469, 464, - 471, 669, 319, 57, 724, 725, 726, 289, 727, 511, - 512, 513, 514, 11, 565, 548, 576, 549, 566, 550, - 559, 551, 567, 575, 577, 532, 540, 533, 541, 571, - 554, 568, 560, 553, 552, 574, 557, 561, 534, 542, - 572, 558, 535, 543, 536, 544, 537, 545, 570, 569, - 562, 573, 538, 546, 564, 539, 547, 563, 555, 556, - 434, 734, 735, 506, 401, 129, 299, 300, 49, 353, - 281, 670, 312, 671, 343, 344, 479, 480, 358, 329, - 354, 687, 320, 685, 283, 402, 484, 269, 672, 424, - 296, 375, 121, 380, 313, 588, 524, 288, 403, 699, - 586, 515, 516, 351, 348, 290, 517, 673, 689, 404, - 244, 284, 285, 674, 686, 405, 406, 306, 407, 408, - 409, 410, 411, 413, 317, 412, 688, 682, 683, 291, - 462, 585, 325, 346, 381, 444, 445, 446, 447, 448, - 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 481, 242, -79, 242, -190, -299, -130, - 691, 693, 181, -271, 385, -289, 387, 400, 395, 405, - 393, -280, 396, 398, 282, -401, 415, 242, 402, 229, - 388, 397, 406, 407, 306, 413, 408, 317, 412, 291, - 409, 410, 411, -385, 181, 712, 727, 138, 350, 392, - 390, 416, 691, 92, -305, 92, 93, 94, -292, 320, - -308, 325, -293, -385, -292, 323, -79, -79, -310, -310, - -130, -209, -145, 146, -159, -260, -162, 93, -150, -153, - -203, -204, -205, -206, -160, -219, -258, 170, 171, 178, - 147, -215, -163, 28, 578, 474, 473, 181, 33, 224, - 70, 71, 476, 477, 149, 59, 13, 439, 440, -161, - 429, 430, 441, 435, 436, 502, 504, 505, 506, 503, - 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, - 507, 518, 479, 480, 119, 481, 109, 111, 110, 482, - 483, 484, 347, 530, 531, 525, 528, 529, 527, 526, - 362, 363, 485, 548, 549, 553, 552, 550, 551, 554, - 557, 558, 559, 560, 561, 562, 564, 563, 555, 556, - 533, 532, 534, 535, 536, 537, 538, 539, 541, 540, - 542, 543, 544, 545, 546, 547, 565, 566, 567, 568, - 569, 571, 570, 575, 574, 572, 573, 577, 576, 486, - 487, 112, 113, 114, 115, 116, 117, 118, 488, 491, - 489, 490, 492, 493, 494, 499, 500, 495, 496, 497, - 498, 501, 373, 371, 372, 368, 367, 366, -89, -102, - 605, 604, -103, 426, 431, 432, 434, -151, -152, -165, - -166, -293, -299, 247, 428, 241, 176, 472, -154, -148, - -217, 108, 94, -31, -213, 427, 437, 438, 442, 433, - 443, 591, 593, 608, 609, 611, 596, 601, 600, 603, - 519, 520, 521, 522, 523, 524, 676, 677, 678, 679, - 680, 681, 682, 683, -385, -292, 92, -157, -155, -199, - 95, 100, 103, 104, 106, -407, 265, 343, 344, 120, - -417, 705, -156, 97, 98, 99, 122, 123, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 91, 96, 46, 401, 401, -190, -79, -79, -79, -79, - -414, 708, 583, -229, -128, -231, -33, -31, -417, 10, - -79, -31, -32, -30, -36, -38, 610, -37, -299, 101, - -236, -252, 14, 63, 165, 44, 52, -234, -235, -34, - -31, -145, 21, 25, 26, -132, 172, -145, -299, -132, - -278, 246, -79, -79, -267, -313, 320, -269, 416, 691, - 415, -259, -272, 92, -258, -271, 414, 93, -355, 162, - -341, -345, -293, 257, -371, 253, -190, -364, -363, -293, - -417, -129, -288, 243, 251, 250, 139, -388, 142, 299, - 428, 241, -53, -54, -55, -271, 180, 711, -111, 274, - 278, 89, 89, -345, -344, -343, -389, 278, 257, -370, - -362, 249, 258, -351, 250, 251, -346, 243, 140, -389, - -346, 248, 258, 253, 257, 278, 278, 129, 278, 129, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 273, - -352, 154, -352, 586, 586, -358, -389, 253, 243, -389, - -389, 249, -290, -346, 245, 27, 245, 37, 37, -352, - -352, -352, -271, 180, -352, -352, -352, -352, 286, 286, - -352, -352, -352, -352, -352, -352, -352, -352, -352, -352, - -352, -352, -352, -352, -352, -352, -352, 242, -388, -137, - 412, 306, 83, -56, 288, -39, -190, -288, 243, 244, - -388, 275, -190, 225, 242, 694, -282, 162, 17, -282, - -279, 401, 399, 386, 391, -282, -282, -282, -282, 289, - 384, -347, 243, 37, 254, 401, 289, 384, 289, 290, - 289, 290, 394, 404, 289, -304, 16, 165, 428, 389, - 393, 282, 242, 283, 244, 403, 290, -304, 91, -283, - 162, 289, 401, 395, 285, -282, -282, -311, -417, -295, - -293, -291, 234, 25, 145, 27, 29, 148, 181, 132, - 21, 149, 39, 236, 350, 253, 180, 249, 473, 229, - 74, 591, 429, 436, 427, 435, 439, 475, 476, 428, - 387, 33, 15, 593, 30, 263, 26, 40, 174, 231, - 152, 594, 266, 28, 264, 119, 123, 596, 24, 77, - 258, 16, 251, 42, 18, 597, 598, 19, 247, 246, - 165, 243, 72, 13, 224, 31, 161, 68, 599, 140, - 135, 600, 601, 602, 603, 133, 70, 162, 22, 731, - 437, 438, 35, 692, 578, 277, 176, 75, 61, 693, - 146, 433, 604, 605, 120, 606, 124, 78, 698, 142, - 20, 73, 44, 607, 278, 608, 248, 732, 609, 419, - 610, 163, 232, 472, 71, 164, 705, 611, 706, 241, - 400, 10, 478, 34, 262, 250, 131, 69, 443, 612, - 242, 151, 245, 134, 122, 9, 139, 36, 14, 76, - 79, 440, 441, 442, 59, 130, 582, 150, 17, 613, - 420, 144, -385, 694, -311, -311, 34, 93, -411, -412, - -413, 582, 419, 245, -293, -190, -85, 684, 233, -86, - 690, 25, 240, -135, 401, -123, 181, 712, 695, 696, - 697, 694, 398, 702, 700, 698, 289, 699, 89, 142, - 144, 145, 4, -145, 161, -200, 154, 155, 156, 157, - 158, 159, 160, 166, 165, 146, 148, 162, -245, 143, - 167, 168, 169, 170, 171, 172, 173, 175, 174, 176, - 177, 163, 164, 180, 227, 228, -153, -153, -153, -153, - -215, -221, -220, -417, -217, -385, -292, -299, -417, -417, - -153, -277, -417, -150, -417, -417, -417, -417, -417, -224, - -145, -417, -417, -421, -417, -421, -421, -421, -330, -417, - -330, -330, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, -417, -417, -417, -417, 225, -417, -417, -417, -417, - -417, -330, -330, -330, -330, -330, -330, -417, -417, -417, - -417, -417, -417, -417, -417, -417, -417, -417, -417, -417, - -417, 91, 104, 100, 103, 95, -219, 106, 91, 91, - 91, 91, -31, -32, -209, -417, -310, -398, -399, -193, - -190, -417, 306, -293, -293, 275, 97, -234, -34, -31, - -229, -235, -231, -31, -79, -121, -134, 65, 66, -133, - -136, 26, 40, 69, 67, 25, -418, 90, -418, -252, - -418, 89, -38, -255, 88, 638, 668, 638, 668, 63, - 45, 91, 91, 89, 23, -230, -232, -145, 16, -297, - 4, -296, 27, -293, 91, 225, 16, -191, 31, -190, - -278, -278, 89, 92, 320, -268, -270, 417, 419, 154, - -298, -293, 91, 33, 90, 89, -190, -319, -322, -324, - -323, -325, -320, -321, 347, 348, 181, 351, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 364, 34, 265, - 343, 344, 345, 346, 365, 366, 367, 368, 370, 371, - 372, 373, 328, 349, 580, 329, 330, 331, 332, 333, - 334, 336, 337, 340, 338, 339, 341, 342, -294, -293, - 88, 90, 89, -329, 88, -145, -137, 242, -293, 243, - 243, 243, -79, 472, -352, -352, -352, 273, 21, -46, - -43, -378, 20, -42, -43, 234, 125, 126, 231, 88, - -341, 88, -350, -294, -293, 88, 140, 248, 139, -349, - -346, -349, -350, -293, -217, -293, 140, 140, -293, -293, - -264, -293, -264, -264, 25, -264, 25, -264, 25, 97, - -293, -264, 25, -264, 25, -264, 25, -264, 25, -264, - 25, 33, 80, 81, 82, 33, 84, 85, 86, -217, - -293, -293, -217, -341, -217, -190, -293, -271, 97, 97, - 97, -352, -352, 97, 91, 91, 91, -352, -352, 97, - 91, -301, -299, 91, 91, -390, 259, 303, 305, 97, - 97, 97, 97, 33, 91, -391, 33, 719, 718, 720, - 721, 722, 91, 97, 33, 97, 33, 97, -293, 88, - -190, -143, 293, 229, 231, 234, 78, 91, 309, 310, - 307, 312, 313, 314, 154, 46, 89, 245, 242, -293, - -284, 247, -284, -293, -300, -299, -291, -190, 245, 383, - 91, -145, -348, 16, 165, -304, -304, -282, -190, -348, - -304, -282, -190, -282, -282, -282, -282, -304, -304, -304, - -282, -299, -299, -190, -190, -190, -190, -190, -190, -190, - -311, -283, -282, 694, 91, -276, 16, 78, -311, -311, - 89, 326, 420, 421, -309, 323, -81, -293, 91, -10, - -29, -18, -17, -19, 154, -10, 89, 582, -183, -190, - 694, 694, 694, 694, 694, 694, -145, -145, -145, -145, - 606, -207, -409, 146, 122, 123, 120, 121, -162, -145, - -208, -213, -215, 107, 165, 148, 162, -245, -150, -153, - -150, -150, -150, -150, -150, -150, 224, -150, 224, -150, - -150, -150, -150, -150, -150, -312, -293, 91, 181, -158, - -157, 106, -407, -158, 579, 89, -220, 225, -145, -145, - -385, -119, 445, 446, 447, 448, 450, 451, 452, 455, - 456, 460, 461, 444, 462, 449, 454, 457, 458, 459, - 453, 346, -145, -210, -209, -210, -145, -145, -222, -223, - 150, -217, -145, -418, -418, 97, 172, -127, 26, 40, - -127, -127, -127, -127, -145, -145, -145, -145, -145, -145, - -145, -145, -145, -145, -127, -145, -120, 444, 462, 449, - 454, 457, 458, 459, 453, 346, 463, 464, 465, 466, - 467, 468, 469, 470, 471, -120, -119, -145, -145, -145, - -145, -145, -145, -87, -145, 132, 133, 134, -209, -145, - -150, -145, -145, -145, -418, -145, -145, -145, -210, -145, + -8, -32, -31, -30, 12, 13, -109, -35, 34, -40, + -50, 232, -51, -41, 233, -52, 235, 234, 272, 236, + 385, 265, 79, 321, 322, 324, 325, 326, 327, -110, + 692, 270, 271, 238, 38, 50, 35, 36, 39, 242, + 278, 279, 241, 138, -33, -36, 11, -418, 14, 475, + 267, 266, 30, -34, 585, 91, -80, -417, 740, -253, + -237, 25, 35, 31, -236, -232, -128, -237, 23, 21, + 10, -79, -79, -79, 15, 16, -79, -355, -357, 91, + 165, 91, -79, -57, -56, -54, -53, -55, -58, 33, + -47, -48, -379, -46, -43, 237, 234, 282, 128, 129, + 272, 273, 274, 236, 256, 271, 275, 270, 291, -42, + 86, 35, 585, 588, -362, 233, 239, 240, 235, 476, + 131, 130, 80, -359, 380, 619, 710, -58, 712, 105, + 108, 711, 49, 246, 713, 714, 715, 626, 716, 255, + 717, 718, 719, 720, 726, 667, 727, 728, 729, 132, + 10, -79, -304, -300, 95, -293, 582, 258, 617, 429, + 618, 307, 86, 46, 41, 521, 592, 377, 380, 619, + 506, 710, 386, 321, 337, 331, 511, 512, 513, 360, + 352, 583, 620, 593, 310, 259, 295, 704, 350, 141, + 712, 314, 621, 273, 387, 388, 622, 389, 105, 324, + 426, 725, 313, 623, 723, 108, 711, 329, 84, 505, + 56, 707, 49, 268, 434, 435, 348, 241, 344, 713, + 296, 624, 595, 289, 131, 128, 732, 38, 340, 55, + 32, 722, 130, 54, 714, 156, 625, 715, 626, 391, + 367, 698, 53, 392, 274, 627, 89, 279, 587, 318, + 706, 393, 526, 341, 394, 306, 721, 238, 628, 317, + 687, 679, 680, 395, 396, 699, 372, 368, 373, 528, + 629, 418, 510, 397, 683, 684, 739, 57, 630, 631, + 700, 129, 632, 83, 716, 85, 335, 336, 633, 304, + 257, 531, 532, 420, 364, 488, 495, 496, 115, 116, + 491, 117, 497, 118, 498, 499, 500, 489, 119, 112, + 490, 501, 502, 365, 366, 120, 503, 114, 113, 492, + 494, 121, 504, 255, 37, 398, 584, 308, 63, 312, + 283, 421, 51, 370, 736, 50, 694, 533, 634, 697, + 363, 359, 485, 58, 635, 636, 637, 638, 507, 717, + 362, 334, 358, 731, 4, 301, 480, 508, 718, 67, + 240, 375, 374, 376, 290, 417, 355, 639, 640, 641, + 262, 87, 642, 345, 24, 643, 644, 399, 297, 645, + 61, 646, 647, 424, 271, 648, 59, 719, 44, 649, + 276, 733, 720, 650, 651, 652, 693, 653, 278, 654, + 401, 655, 681, 682, 400, 369, 371, 534, 285, 402, + 385, 243, 586, 656, 319, 339, 275, 724, 657, 263, + 522, 523, 524, 525, 705, 530, 529, 277, 282, 270, + 425, 264, 658, 659, 660, 661, 662, 311, 678, 663, + 664, 325, 590, 726, 486, 48, 665, 666, 667, 668, + 669, 305, 300, 419, 428, 66, 88, 382, 670, 671, + 703, 333, 330, 42, 298, 466, 468, 469, 470, 471, + 472, 467, 474, 672, 322, 60, 727, 728, 729, 292, + 730, 514, 515, 516, 517, 12, 568, 551, 579, 552, + 569, 553, 562, 554, 570, 578, 580, 535, 543, 536, + 544, 574, 557, 571, 563, 556, 555, 577, 560, 564, + 537, 545, 575, 561, 538, 546, 539, 547, 540, 548, + 573, 572, 565, 576, 541, 549, 567, 542, 550, 566, + 558, 559, 437, 737, 738, 509, 404, 132, 302, 303, + 52, 356, 284, 673, 315, 674, 346, 347, 482, 483, + 361, 332, 357, 690, 323, 688, 286, 405, 487, 272, + 675, 427, 299, 378, 124, 383, 316, 591, 527, 291, + 406, 702, 589, 518, 519, 354, 351, 293, 520, 676, + 692, 407, 247, 287, 288, 677, 689, 408, 409, 309, + 410, 411, 412, 413, 414, 416, 320, 415, 691, 685, + 686, 294, 465, 588, 328, 349, 384, 447, 448, 449, + 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 484, 245, -79, 245, -190, + -300, -130, 694, 696, 184, -272, 388, -290, 390, 403, + 398, 408, 396, -281, 399, 401, 285, -402, 418, 245, + 405, 232, 391, 400, 409, 410, 309, 416, 411, 320, + 415, 294, 412, 413, 414, -386, 184, 715, 730, 141, + 353, 395, 393, 419, 694, 95, -306, 95, 96, 97, + -293, 323, -309, 328, -294, -386, -293, 326, -79, -79, + -311, -311, -130, -210, -145, 149, -159, -261, -162, 96, + -150, -153, -204, -205, -206, -207, -160, -220, -259, 173, + 174, 181, 150, -216, -163, 28, 581, 477, 476, 184, + 33, 227, 73, 74, 479, 480, 152, 62, 14, 442, + 443, -161, 432, 433, 444, 438, 439, 505, 507, 508, + 509, 506, 511, 512, 513, 514, 515, 516, 517, 518, + 519, 520, 510, 521, 482, 483, 122, 484, 112, 114, + 113, 485, 486, 487, 350, 533, 534, 528, 531, 532, + 530, 529, 365, 366, 488, 551, 552, 556, 555, 553, + 554, 557, 560, 561, 562, 563, 564, 565, 567, 566, + 558, 559, 536, 535, 537, 538, 539, 540, 541, 542, + 544, 543, 545, 546, 547, 548, 549, 550, 568, 569, + 570, 571, 572, 574, 573, 578, 577, 575, 576, 580, + 579, 489, 490, 115, 116, 117, 118, 119, 120, 121, + 491, 494, 492, 493, 495, 496, 497, 502, 503, 498, + 499, 500, 501, 504, 376, 374, 375, 371, 370, 369, + -89, -102, 608, 607, -103, 429, 434, 435, 437, -151, + -152, -165, -166, -294, -300, 250, 431, 244, 179, 475, + -154, -148, -218, 111, 97, -31, -214, 430, 440, 441, + 445, 436, 446, 594, 596, 611, 612, 614, 599, 604, + 603, 606, 522, 523, 524, 525, 526, 527, 679, 680, + 681, 682, 683, 684, 685, 686, -386, -293, 95, -157, + -155, -199, 98, 103, 106, 107, 109, -408, 268, 346, + 347, 123, -418, 708, -156, 100, 101, 102, 125, 126, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 94, 99, 49, 404, 404, -190, -79, -79, + -79, -79, -415, 711, 586, -230, -128, -232, -33, -31, + -418, 11, -79, -31, -32, -30, -36, -38, 613, -37, + -300, 104, -237, -253, 15, 66, 168, 47, 55, -235, + -236, -34, -31, -145, 22, 40, 26, -132, 175, -145, + -300, -132, -279, 249, -79, -79, -268, -314, 323, -270, + 419, 694, 418, -260, -273, 95, -259, -272, 417, 96, + -356, 165, -342, -346, -294, 260, -372, 256, -190, -365, + -364, -294, -418, -129, -289, 246, 254, 253, 142, -389, + 145, 302, 431, 244, -53, -54, -55, -272, 183, 714, + -111, 277, 281, 92, 92, -346, -345, -344, -390, 281, + 260, -371, -363, 252, 261, -352, 253, 254, -347, 246, + 143, -390, -347, 251, 261, 256, 260, 281, 281, 132, + 281, 132, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 276, -353, 157, -353, 589, 589, -359, -390, 256, + 246, -390, -390, 252, -291, -347, 248, 27, 248, 37, + 37, -353, -353, -353, -272, 183, -353, -353, -353, -353, + 289, 289, -353, -353, -353, -353, -353, -353, -353, -353, + -353, -353, -353, -353, -353, -353, -353, -353, -353, 245, + -389, -137, 415, 309, 86, -56, 291, -39, -190, -289, + 246, 247, -389, 278, -190, 228, 245, 697, -283, 165, + 18, -283, -280, 404, 402, 389, 394, -283, -283, -283, + -283, 292, 387, -348, 246, 37, 257, 404, 292, 387, + 292, 293, 292, 293, 397, 407, 292, -305, 17, 168, + 431, 392, 396, 285, 245, 286, 247, 406, 293, -305, + 94, -284, 165, 292, 404, 398, 288, -283, -283, -312, + -418, -296, -294, -292, 237, 40, 148, 27, 29, 151, + 184, 135, 22, 152, 39, 239, 353, 256, 183, 252, + 476, 232, 77, 594, 432, 439, 430, 438, 442, 478, + 479, 431, 390, 33, 16, 596, 30, 266, 26, 43, + 177, 234, 155, 597, 269, 28, 267, 122, 126, 599, + 25, 80, 261, 17, 254, 45, 19, 600, 601, 20, + 250, 249, 168, 246, 75, 14, 227, 31, 164, 71, + 602, 143, 138, 603, 604, 605, 606, 136, 73, 165, + 23, 734, 440, 441, 35, 695, 581, 280, 179, 78, + 64, 696, 149, 436, 607, 608, 123, 609, 127, 81, + 701, 145, 21, 76, 47, 610, 281, 611, 251, 735, + 612, 422, 613, 166, 235, 475, 74, 167, 708, 614, + 709, 244, 403, 11, 481, 34, 265, 253, 134, 72, + 446, 615, 245, 154, 248, 137, 125, 10, 142, 36, + 15, 79, 82, 443, 444, 445, 62, 133, 585, 153, + 18, 616, 423, 147, -386, 697, -312, -312, 34, 96, + -412, -413, -414, 585, 422, 248, -294, -190, -85, 687, + 236, -86, 693, 40, 243, -135, 404, -123, 184, 715, + 698, 699, 700, 697, 401, 705, 703, 701, 292, 702, + 92, 145, 147, 148, 4, -145, 164, -200, -201, 163, + 157, 158, 159, 160, 161, 162, 169, 168, 149, 151, + 165, -246, 146, 170, 171, 172, 173, 174, 175, 176, + 178, 177, 179, 180, 166, 167, 183, 230, 231, -153, + -153, -153, -153, -216, -222, -221, -418, -218, -386, -293, + -300, -418, -418, -153, -278, -418, -150, -418, -418, -418, + -418, -418, -225, -145, -418, -418, -422, -418, -422, -422, + -422, -331, -418, -331, -331, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, -418, -418, -418, -418, 228, -418, + -418, -418, -418, -418, -331, -331, -331, -331, -331, -331, + -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, + -418, -418, -418, -418, 94, 107, 103, 106, 98, -220, + 109, 94, 94, 94, 94, -31, -32, -210, -418, -311, + -399, -400, -193, -190, -418, 309, -294, -294, 278, 100, + -235, -34, -31, -230, -236, -232, -31, -79, -121, -134, + 68, 69, -133, -136, 26, 43, 72, 70, 40, -419, + 93, -419, -253, -419, 92, -38, -256, 91, 641, 671, + 641, 671, 66, 48, 94, 94, 92, 24, -231, -233, + -145, 17, -298, 4, -297, 27, -294, 94, 228, 17, + -191, 31, -190, -279, -279, 92, 95, 323, -269, -271, + 420, 422, 157, -299, -294, 94, 33, 93, 92, -190, + -320, -323, -325, -324, -326, -321, -322, 350, 351, 184, + 354, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 367, 34, 268, 346, 347, 348, 349, 368, 369, 370, + 371, 373, 374, 375, 376, 331, 352, 583, 332, 333, + 334, 335, 336, 337, 339, 340, 343, 341, 342, 344, + 345, -295, -294, 91, 93, 92, -330, 91, -145, -137, + 245, -294, 246, 246, 246, -79, 475, -353, -353, -353, + 276, 22, -46, -43, -379, 21, -42, -43, 237, 128, + 129, 234, 91, -342, 91, -351, -295, -294, 91, 143, + 251, 142, -350, -347, -350, -351, -294, -218, -294, 143, + 143, -294, -294, -265, -294, -265, -265, 40, -265, 40, + -265, 40, 100, -294, -265, 40, -265, 40, -265, 40, + -265, 40, -265, 40, 33, 83, 84, 85, 33, 87, + 88, 89, -218, -294, -294, -218, -342, -218, -190, -294, + -272, 100, 100, 100, -353, -353, 100, 94, 94, 94, + -353, -353, 100, 94, -302, -300, 94, 94, -391, 262, + 306, 308, 100, 100, 100, 100, 33, 94, -392, 33, + 722, 721, 723, 724, 725, 94, 100, 33, 100, 33, + 100, -294, 91, -190, -143, 296, 232, 234, 237, 81, + 94, 312, 313, 310, 315, 316, 317, 157, 49, 92, + 248, 245, -294, -285, 250, -285, -294, -301, -300, -292, + -190, 248, 386, 94, -145, -349, 17, 168, -305, -305, + -283, -190, -349, -305, -283, -190, -283, -283, -283, -283, + -305, -305, -305, -283, -300, -300, -190, -190, -190, -190, + -190, -190, -190, -312, -284, -283, 697, 94, -277, 17, + 81, -312, -312, 92, 329, 423, 424, -310, 326, -81, + -294, 94, -10, -29, -18, -17, -19, 157, -10, 92, + 585, -183, -190, 697, 697, 697, 697, 697, 697, -145, + -145, -145, -145, 609, -208, -410, 149, 125, 126, 123, + 124, -162, 41, 42, 40, -145, -209, -214, -216, 110, + 168, 151, 165, -246, -150, -153, -150, -150, -150, -150, + -150, -150, 227, -150, 227, -150, -150, -150, -150, -150, + -150, -313, -294, 94, 184, -158, -157, 109, -408, -158, + 582, 92, -221, 228, -145, -145, -386, -119, 448, 449, + 450, 451, 453, 454, 455, 458, 459, 463, 464, 447, + 465, 452, 457, 460, 461, 462, 456, 349, -145, -211, + -210, -211, -145, -145, -223, -224, 153, -218, -145, -419, + -419, 100, 175, -127, 26, 43, -127, -127, -127, -127, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, + -127, -145, -120, 447, 465, 452, 457, 460, 461, 462, + 456, 349, 466, 467, 468, 469, 470, 471, 472, 473, + 474, -120, -119, -145, -145, -145, -145, -145, -145, -87, + -145, 135, 136, 137, -210, -145, -150, -145, -145, -145, + -419, -145, -145, -145, -211, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, - -145, -145, -145, -145, -145, -384, -383, -382, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, + -145, -385, -384, -383, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, - -145, -209, -209, -209, -209, -209, -145, -418, -145, -164, - -148, 97, -260, 106, 93, -145, -145, -145, -145, -145, - -145, -210, -295, -300, -291, -292, -209, -210, -210, -209, - -209, -145, -145, -145, -145, -145, -145, -145, -145, -418, - -145, -145, -145, -145, -145, -252, -418, -209, 89, -400, - 419, 420, 692, -302, 278, -301, 27, -210, 91, 16, - -262, 79, -293, -234, -234, 65, 66, 61, -131, -132, - -136, -418, -37, 27, -254, -293, 631, 631, 64, 91, - -331, -271, 374, 375, 181, -145, -145, 89, -233, 29, - 30, -190, -296, 172, -300, -190, -263, 278, -190, -168, - -170, -171, -172, -193, -216, -417, -173, -31, 602, 599, - 16, -183, -184, -192, -299, -269, -313, -268, 89, 418, - 420, 421, 78, 124, -145, -332, 180, -360, -359, -358, - -341, -343, -344, -345, 90, -332, -337, 380, 379, -329, - -329, -329, -329, -329, -331, -331, -331, -331, 88, 88, - -329, -329, -329, -329, -334, 88, -334, -334, -335, -334, - 88, -335, -336, 88, -336, -371, -145, -368, -367, -365, - -366, 252, 102, 674, 630, 582, 623, 664, 79, -363, - -233, 97, -418, -143, -285, 247, -369, -366, -293, -293, - -293, -285, 92, 91, 92, 91, 92, 91, -112, -60, - -1, 731, 732, 733, 89, 21, -342, -341, -59, 303, - -374, -375, 278, -370, -364, -350, 140, -349, -350, -350, - -293, 89, 31, 129, 129, 129, 129, 582, 231, 34, - -286, 622, 146, 674, 630, -341, -59, 245, 245, -312, - -312, -312, 91, 91, -281, 727, -183, -139, 295, 154, - 284, 284, 242, 297, 242, 297, -190, 308, 311, 309, - 310, 307, 312, 313, 314, 25, 25, 25, 25, 25, - 25, 296, 298, 300, 286, -190, -190, -284, 78, -185, - -190, 28, -299, 91, 91, -190, -282, -282, -190, -282, - -282, -190, -413, 327, -293, 361, 685, 687, -123, 419, - 89, 582, 24, -124, 24, -417, -409, 122, 123, -208, - -150, -153, -150, 145, 266, -150, -150, -417, -217, -418, - -295, 27, 89, 79, -418, 170, 89, -418, -418, 89, - 16, 89, -225, -223, 152, -145, -418, 89, -418, -418, - -209, -145, -145, -145, -145, -418, -418, -418, -418, -418, - -418, -418, -418, -418, -418, -209, -418, 89, 89, 16, - -316, 27, -418, -418, -418, -418, -418, -224, -418, 16, - -418, 79, 89, 165, 89, -418, -418, -418, 89, 89, - -418, -418, 89, -418, 89, -418, -418, -418, -418, -418, - -418, 89, -418, 89, -418, -418, -418, 89, -418, 89, - -418, -418, 89, -418, 89, -418, 89, -418, 89, -418, - 89, -418, 89, -418, 89, -418, 89, -418, 89, -418, - 89, -418, 89, -418, 89, -418, 89, -418, 89, -418, - 89, -418, 89, -418, 89, -418, 89, -418, -418, -418, - 89, -418, 89, -418, 89, -418, -418, 89, -418, 89, - -418, 89, -418, 89, 89, -418, 89, 89, 89, -418, - 89, 89, 89, 89, -418, -418, -418, -418, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, -418, -418, - -418, -418, -418, -418, 89, -94, 607, -418, -418, 89, - -418, 89, 89, 89, 89, 89, -418, -417, 225, -418, - -418, -418, -418, -418, 89, 89, 89, 89, 89, 89, - -418, -418, -418, 89, 89, -418, 89, -418, 89, -418, - -399, 691, 420, -197, -196, -194, 76, 246, 77, -417, - -301, -418, -158, -260, -261, -260, -202, -293, 97, 106, - -236, -167, 89, -169, 16, -215, 90, 89, -331, -240, - -246, -279, -293, 91, 181, -333, 181, -333, 374, 375, - -232, 225, -198, 17, -201, 34, 59, -29, -417, -417, - 34, 89, -186, -188, -187, -189, 68, 72, 74, 69, - 70, 71, 75, -307, 27, -31, -168, -31, -417, -190, - -183, -419, 16, 79, -419, 89, 225, -270, -273, 422, - 419, 425, -385, 91, -111, 89, -358, -345, -237, -140, - 42, -338, 381, -331, 590, -331, -340, 91, -340, 97, - 97, 97, 90, -49, -44, -45, 35, 83, -365, -352, - 91, 41, -352, -352, -293, 90, -233, -139, -190, 146, - 78, -369, -369, -369, -299, -2, 730, 736, 140, 88, - 386, 20, -254, 89, 90, -218, 304, 90, -113, -293, - 90, 88, -350, -350, -293, -417, 242, 33, 33, 674, - 630, 622, -59, -218, -217, -293, -332, 729, 728, 90, - 244, 302, -144, 439, -141, 91, 92, -190, -190, -190, - -190, -190, -190, 234, 231, 409, -408, 315, -408, 287, - 245, -183, -190, 89, -84, 261, 256, -304, -304, 35, - -190, 419, 703, 701, -145, 145, 266, -162, -153, -119, - -119, -150, -314, 181, 347, 265, 345, 341, 361, 352, - 379, 343, 380, 338, 337, 336, -314, -312, -150, -209, - -145, -145, -145, 153, -145, 151, -145, -95, -94, -418, - -418, -418, -418, -418, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -229, -145, -145, -145, -418, 181, - 347, 16, -145, -312, -145, -145, -145, -145, -145, -145, + -145, -145, -145, -145, -145, -145, -145, -210, -210, -210, + -210, -210, -145, -419, -145, -164, -148, 100, -261, 109, + 96, -145, -145, -145, -145, -145, -145, -211, -296, -301, + -292, -293, -210, -211, -211, -210, -210, -145, -145, -145, + -145, -145, -145, -145, -145, -419, -145, -145, -145, -145, + -145, -253, -419, -210, 92, -401, 422, 423, 695, -303, + 281, -302, 27, -211, 94, 17, -263, 82, -294, -235, + -235, 68, 69, 64, -131, -132, -136, -419, -37, 27, + -255, -294, 634, 634, 67, 94, -332, -272, 377, 378, + 184, -145, -145, 92, -234, 29, 30, -190, -297, 175, + -301, -190, -264, 281, -190, -168, -170, -171, -172, -193, + -217, -418, -173, -31, 605, 602, 17, -183, -184, -192, + -300, -270, -314, -269, 92, 421, 423, 424, 81, 127, + -145, -333, 183, -361, -360, -359, -342, -344, -345, -346, + 93, -333, -338, 383, 382, -330, -330, -330, -330, -330, + -332, -332, -332, -332, 91, 91, -330, -330, -330, -330, + -335, 91, -335, -335, -336, -335, 91, -336, -337, 91, + -337, -372, -145, -369, -368, -366, -367, 255, 105, 677, + 633, 585, 626, 667, 82, -364, -234, 100, -419, -143, + -286, 250, -370, -367, -294, -294, -294, -286, 95, 94, + 95, 94, 95, 94, -112, -60, -1, 734, 735, 736, + 92, 22, -343, -342, -59, 306, -375, -376, 281, -371, + -365, -351, 143, -350, -351, -351, -294, 92, 31, 132, + 132, 132, 132, 585, 234, 34, -287, 625, 149, 677, + 633, -342, -59, 248, 248, -313, -313, -313, 94, 94, + -282, 730, -183, -139, 298, 157, 287, 287, 245, 300, + 245, 300, -190, 311, 314, 312, 313, 310, 315, 316, + 317, 40, 40, 40, 40, 40, 40, 299, 301, 303, + 289, -190, -190, -285, 81, -185, -190, 28, -300, 94, + 94, -190, -283, -283, -190, -283, -283, -190, -414, 330, + -294, 364, 688, 690, -123, 422, 92, 585, 25, -124, + 25, -418, -410, 125, 126, -216, -216, -216, -209, -150, + -153, -150, 148, 269, -150, -150, -418, -218, -419, -296, + 27, 92, 82, -419, 173, 92, -419, -419, 92, 17, + 92, -226, -224, 155, -145, -419, 92, -419, -419, -210, + -145, -145, -145, -145, -419, -419, -419, -419, -419, -419, + -419, -419, -419, -419, -210, -419, 92, 92, 17, -317, + 27, -419, -419, -419, -419, -419, -225, -419, 17, -419, + 82, 92, 168, 92, -419, -419, -419, 92, 92, -419, + -419, 92, -419, 92, -419, -419, -419, -419, -419, -419, + 92, -419, 92, -419, -419, -419, 92, -419, 92, -419, + -419, 92, -419, 92, -419, 92, -419, 92, -419, 92, + -419, 92, -419, 92, -419, 92, -419, 92, -419, 92, + -419, 92, -419, 92, -419, 92, -419, 92, -419, 92, + -419, 92, -419, 92, -419, 92, -419, -419, -419, 92, + -419, 92, -419, 92, -419, -419, 92, -419, 92, -419, + 92, -419, 92, 92, -419, 92, 92, 92, -419, 92, + 92, 92, 92, -419, -419, -419, -419, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, -419, -419, -419, + -419, -419, -419, 92, -94, 610, -419, -419, 92, -419, + 92, 92, 92, 92, 92, -419, -418, 228, -419, -419, + -419, -419, -419, 92, 92, 92, 92, 92, 92, -419, + -419, -419, 92, 92, -419, 92, -419, 92, -419, -400, + 694, 423, -197, -196, -194, 79, 249, 80, -418, -302, + -419, -158, -261, -262, -261, -203, -294, 100, 109, -237, + -167, 92, -169, 17, -216, 93, 92, -332, -241, -247, + -280, -294, 94, 184, -334, 184, -334, 377, 378, -233, + 228, -198, 18, -202, 34, 62, -29, -418, -418, 34, + 92, -186, -188, -187, -189, 71, 75, 77, 72, 73, + 74, 78, -308, 27, -31, -168, -31, -418, -190, -183, + -420, 17, 82, -420, 92, 228, -271, -274, 425, 422, + 428, -386, 94, -111, 92, -359, -346, -238, -140, 45, + -339, 384, -332, 593, -332, -341, 94, -341, 100, 100, + 100, 93, -49, -44, -45, 35, 86, -366, -353, 94, + 44, -353, -353, -294, 93, -234, -139, -190, 149, 81, + -370, -370, -370, -300, -2, 733, 739, 143, 91, 389, + 21, -255, 92, 93, -219, 307, 93, -113, -294, 93, + 91, -351, -351, -294, -418, 245, 33, 33, 677, 633, + 625, -59, -219, -218, -294, -333, 732, 731, 93, 247, + 305, -144, 442, -141, 94, 95, -190, -190, -190, -190, + -190, -190, 237, 234, 412, -409, 318, -409, 290, 248, + -183, -190, 92, -84, 264, 259, -305, -305, 35, -190, + 422, 706, 704, -145, 148, 269, -162, -153, -119, -119, + -150, -315, 184, 350, 268, 348, 344, 364, 355, 382, + 346, 383, 341, 340, 339, -315, -313, -150, -210, -145, + -145, -145, 156, -145, 154, -145, -95, -94, -419, -419, + -419, -419, -419, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -230, -145, -145, -145, -419, 184, 350, + 17, -145, -313, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, - -145, -145, -145, -145, -145, -145, -145, -145, -145, -382, - -145, -209, -145, -209, -145, -145, -145, -145, -145, -383, - -383, -383, -383, -383, -209, -209, -209, -209, -145, -417, - -293, -98, -97, -96, 657, 246, -94, -164, -98, -164, - 224, -145, 224, 224, 224, -145, -210, -295, -145, -145, - -145, -145, -145, -145, -145, -145, -145, -145, -194, -346, - 284, -346, 284, -346, -264, 89, -275, 24, 16, 59, - 59, -167, -198, -132, -168, -293, -243, 684, -249, 48, - -247, -248, 49, -244, 50, 58, -333, -333, 172, -234, - -145, -265, 78, -266, -274, -217, -212, -214, -213, -417, - -253, -418, -293, -264, -266, -170, -171, -171, -170, -171, - 68, 68, 68, 73, 68, 73, 68, -187, -299, -418, - -145, -302, 79, -168, -168, -192, -299, 172, 419, 423, - 424, -358, -406, 120, 146, 33, 78, 377, 102, -404, - 180, 619, 669, 674, 630, 623, 664, -405, 248, 139, - 140, 260, 27, 43, 90, 89, 90, 89, 90, 90, - 89, -287, -286, -45, -44, -352, -352, 97, -385, 91, - 91, 244, 28, -190, 78, 78, 78, -114, 734, 97, - 88, -3, 83, -145, 88, 21, -341, -217, -376, -326, - -377, -327, -328, -5, -6, -353, -117, 59, 102, -63, - 46, 243, 714, 715, 129, -417, 727, -368, -254, -372, - -374, -190, -149, -417, -161, -147, -146, -148, -154, 170, - 171, 265, 343, 344, -218, -190, -138, 293, 301, 88, - -142, 93, -387, 79, 284, 377, 284, 377, 91, -410, - 316, 91, -410, -190, -84, -49, -190, -282, -282, 35, - -385, -418, -162, -153, -126, 165, 582, -317, 589, -329, - -329, -329, -336, -329, 333, -329, 333, -329, -418, -418, - -418, 89, -418, 24, -418, 89, -145, 89, -95, -95, - -95, -95, -95, -122, 478, 89, 89, -418, 88, 88, - -145, -418, -418, -418, 89, -418, -418, -418, -418, -418, - -418, -418, -418, -418, -418, -418, -418, -418, 89, -418, - 89, -418, 89, -418, 89, -418, 89, -418, 89, -418, - 89, -418, 89, -418, 89, -418, 89, -418, 89, -418, - 89, -418, 89, -418, 89, -418, 89, -418, 89, -418, - -418, 89, -418, -418, -418, 89, -418, 89, -418, 89, - -418, -418, -418, 89, -315, 675, -418, -418, -418, -418, - -418, -418, -418, -418, -418, -418, -418, -93, -294, -94, - 639, 639, -418, -94, -226, 89, -150, -418, -150, -150, - -150, -418, -418, -418, 89, -418, 89, 89, -418, 89, - -418, 89, -418, -418, -418, -418, 89, -195, 24, -417, - -195, -417, -195, -418, -260, -190, -198, -227, 18, -240, - 53, 353, -251, -250, 57, 49, -248, 21, 51, 21, - 32, -265, 89, 154, -306, 89, 27, -418, -418, 89, - 59, 225, -418, -198, -181, -180, 78, 79, -182, 78, - -180, 68, 68, -255, 89, -263, -168, -198, -198, 225, - 120, -417, -149, 14, 91, 91, -385, -403, 718, 719, - 33, 97, -352, -352, 140, 140, -190, 88, -331, 91, - -331, 97, 97, 33, 84, 85, 86, 33, 80, 81, - 82, -190, -190, -190, -190, -373, 88, 21, -145, 88, - 154, 90, -254, -254, 280, 165, -352, 712, 286, 286, - -352, -352, -352, -116, -115, 734, 90, -418, 89, -339, - 582, 585, -145, -155, -155, -255, 90, -381, 582, -386, - -293, -293, -293, -293, 97, 99, -418, 580, 75, 583, - -418, -331, -145, -145, -145, -145, -234, 91, -145, -145, - 97, 97, -418, -145, -145, -145, -145, -145, -145, -145, + -145, -145, -145, -145, -145, -145, -145, -145, -383, -145, + -210, -145, -210, -145, -145, -145, -145, -145, -384, -384, + -384, -384, -384, -210, -210, -210, -210, -145, -418, -294, + -98, -97, -96, 660, 249, -94, -164, -98, -164, 227, + -145, 227, 227, 227, -145, -211, -296, -145, -145, -145, + -145, -145, -145, -145, -145, -145, -145, -194, -347, 287, + -347, 287, -347, -265, 92, -276, 25, 17, 62, 62, + -167, -198, -132, -168, -294, -244, 687, -250, 51, -248, + -249, 52, -245, 53, 61, -334, -334, 175, -235, -145, + -266, 81, -267, -275, -218, -213, -215, -214, -418, -254, + -419, -294, -265, -267, -170, -171, -171, -170, -171, 71, + 71, 71, 76, 71, 76, 71, -187, -300, -419, -145, + -303, 82, -168, -168, -192, -300, 175, 422, 426, 427, + -359, -407, 123, 149, 33, 81, 380, 105, -405, 183, + 622, 672, 677, 633, 626, 667, -406, 251, 142, 143, + 263, 27, 46, 93, 92, 93, 92, 93, 93, 92, + -288, -287, -45, -44, -353, -353, 100, -386, 94, 94, + 247, 28, -190, 81, 81, 81, -114, 737, 100, 91, + -3, 86, -145, 91, 22, -342, -218, -377, -327, -378, + -328, -329, -5, -6, -354, -117, 62, 105, -63, 49, + 246, 717, 718, 132, -418, 730, -369, -255, -373, -375, + -190, -149, -418, -161, -147, -146, -148, -154, 173, 174, + 268, 346, 347, -219, -190, -138, 296, 304, 91, -142, + 96, -388, 82, 287, 380, 287, 380, 94, -411, 319, + 94, -411, -190, -84, -49, -190, -283, -283, 35, -386, + -419, -162, -153, -126, 168, 585, -318, 592, -330, -330, + -330, -337, -330, 336, -330, 336, -330, -419, -419, -419, + 92, -419, 25, -419, 92, -145, 92, -95, -95, -95, + -95, -95, -122, 481, 92, 92, -419, 91, 91, -145, + -419, -419, -419, 92, -419, -419, -419, -419, -419, -419, + -419, -419, -419, -419, -419, -419, -419, 92, -419, 92, + -419, 92, -419, 92, -419, 92, -419, 92, -419, 92, + -419, 92, -419, 92, -419, 92, -419, 92, -419, 92, + -419, 92, -419, 92, -419, 92, -419, 92, -419, -419, + 92, -419, -419, -419, 92, -419, 92, -419, 92, -419, + -419, -419, 92, -316, 678, -419, -419, -419, -419, -419, + -419, -419, -419, -419, -419, -419, -93, -295, -94, 642, + 642, -419, -94, -227, 92, -150, -419, -150, -150, -150, + -419, -419, -419, 92, -419, 92, 92, -419, 92, -419, + 92, -419, -419, -419, -419, 92, -195, 25, -418, -195, + -418, -195, -419, -261, -190, -198, -228, 19, -241, 56, + 356, -252, -251, 60, 52, -249, 22, 54, 22, 32, + -266, 92, 157, -307, 92, 27, -419, -419, 92, 62, + 228, -419, -198, -181, -180, 81, 82, -182, 81, -180, + 71, 71, -256, 92, -264, -168, -198, -198, 228, 123, + -418, -149, 15, 94, 94, -386, -404, 721, 722, 33, + 100, -353, -353, 143, 143, -190, 91, -332, 94, -332, + 100, 100, 33, 87, 88, 89, 33, 83, 84, 85, + -190, -190, -190, -190, -374, 91, 22, -145, 91, 157, + 93, -255, -255, 283, 168, -353, 715, 289, 289, -353, + -353, -353, -116, -115, 737, 93, -419, 92, -340, 585, + 588, -145, -155, -155, -256, 93, -382, 585, -387, -294, + -294, -294, -294, 100, 102, -419, 583, 78, 586, -419, + -332, -145, -145, -145, -145, -235, 94, -145, -145, 100, + 100, -419, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, -145, - -145, -145, -145, -209, -145, -418, -178, -177, -179, 695, - 120, 33, -314, -418, -211, 278, -101, -100, -99, 16, - -418, -145, -119, -119, -119, -119, -145, -145, -145, -145, - -145, -145, -417, 68, 20, 18, -257, -293, 248, -417, - -257, -417, -302, -227, -228, 19, 21, -241, 55, -239, - 54, -239, -250, 21, 21, 91, 21, 91, 140, -274, - -145, -214, -301, 59, -29, -293, -212, -293, -229, -145, - 88, -145, -158, -198, -198, -145, -204, 502, 504, 505, - 506, 503, 508, 509, 510, 511, 512, 513, 514, 515, - 516, 517, 507, 518, 479, 480, 481, 109, 111, 110, - 482, 483, 484, 347, 530, 531, 525, 528, 529, 527, - 526, 362, 363, 485, 548, 549, 553, 552, 550, 551, - 554, 557, 558, 559, 560, 561, 562, 564, 563, 555, - 556, 533, 532, 534, 535, 536, 537, 538, 539, 541, - 540, 542, 543, 544, 545, 546, 547, 565, 566, 567, - 568, 569, 571, 570, 575, 574, 572, 573, 577, 576, - 486, 487, 112, 113, 114, 115, 116, 117, 118, 488, - 491, 489, 492, 493, 494, 499, 500, 495, 496, 497, - 498, 501, 373, 371, 372, 368, 367, 366, 426, 431, - 432, 434, 519, 520, 521, 522, 523, 524, 676, 677, - 678, 679, 680, 681, 682, 683, 91, 91, 88, -145, - 90, 90, -255, -372, -60, 90, -256, -254, 97, 90, - 281, -213, -417, 91, -352, -352, -352, 97, 97, -301, - -418, 89, -293, -405, -374, 586, 586, -418, 27, -380, - -379, -295, 88, 79, 64, 581, 584, -418, -418, -418, - 89, -418, -418, -418, 90, 90, -418, -418, -418, -418, - -418, -418, -418, -418, -418, -418, -418, -418, -418, -418, - -418, -418, -418, -418, -418, -418, -418, -418, 89, -418, - -177, -179, -418, 78, -158, -229, 21, -98, 303, 305, - -98, -418, -418, -418, -418, -418, 89, -418, -418, 89, - -418, 89, -418, -418, -257, -418, 21, 21, 89, -418, - -257, -418, -257, -197, -228, -108, -107, -106, 613, -145, - -209, -242, 56, 78, 124, 91, 91, 91, 14, -417, - -212, 225, -306, -234, -254, -175, 386, -229, -418, -254, - 90, 27, 90, 736, 140, 90, -213, -125, -417, 277, - -301, 91, 91, -115, -118, -29, 89, 154, -254, -190, - 64, -145, -209, -418, 78, 594, 695, -92, -91, -88, - 706, 732, -209, -94, -94, -145, -145, -145, -418, -293, - 248, -418, -418, -108, 89, -105, -104, -293, -318, 582, - 78, 124, -266, -254, -306, -293, 90, -418, -417, -234, - 90, -238, -29, 88, -3, 277, -326, -377, -327, -328, - -5, -6, -353, -82, 582, -379, -357, -299, -295, 91, - 97, 90, 582, -418, -418, -90, 148, 704, 672, -155, - 224, -418, 89, -418, 89, -418, 89, -106, 89, 27, - 587, -418, -302, -176, -174, -293, 636, -396, -395, 578, - -406, -402, 120, 146, 102, -404, 674, 630, 130, 131, - -82, -145, 88, -418, -83, 292, 691, 225, -387, 583, - -90, 705, 650, 625, 650, 625, -150, -145, -145, -145, - -104, -417, -418, 89, 24, -319, -62, 647, -393, -394, - 78, -397, 392, 646, 667, 120, 91, 90, -254, 253, - -300, -381, 584, 145, -119, -418, 89, -418, 89, -418, - -93, -174, 643, -332, -158, -394, 78, -393, 78, 15, - 14, -4, 735, 90, 294, -90, 650, 625, -145, -145, - -418, -61, 28, -175, -392, 261, 256, 259, 34, -392, - 97, -4, -418, -418, 647, 255, 33, 120, -158, -178, - -177, -177, + -145, -145, -210, -145, -419, -178, -177, -179, 698, 123, + 33, -315, -419, -212, 281, -101, -100, -99, 17, -419, + -145, -119, -119, -119, -119, -145, -145, -145, -145, -145, + -145, -418, 71, 21, 19, -258, -294, 251, -418, -258, + -418, -303, -228, -229, 20, 22, -242, 58, -240, 57, + -240, -251, 22, 22, 94, 22, 94, 143, -275, -145, + -215, -302, 62, -29, -294, -213, -294, -230, -145, 91, + -145, -158, -198, -198, -145, -205, 505, 507, 508, 509, + 506, 511, 512, 513, 514, 515, 516, 517, 518, 519, + 520, 510, 521, 482, 483, 484, 112, 114, 113, 485, + 486, 487, 350, 533, 534, 528, 531, 532, 530, 529, + 365, 366, 488, 551, 552, 556, 555, 553, 554, 557, + 560, 561, 562, 563, 564, 565, 567, 566, 558, 559, + 536, 535, 537, 538, 539, 540, 541, 542, 544, 543, + 545, 546, 547, 548, 549, 550, 568, 569, 570, 571, + 572, 574, 573, 578, 577, 575, 576, 580, 579, 489, + 490, 115, 116, 117, 118, 119, 120, 121, 491, 494, + 492, 495, 496, 497, 502, 503, 498, 499, 500, 501, + 504, 376, 374, 375, 371, 370, 369, 429, 434, 435, + 437, 522, 523, 524, 525, 526, 527, 679, 680, 681, + 682, 683, 684, 685, 686, 94, 94, 91, -145, 93, + 93, -256, -373, -60, 93, -257, -255, 100, 93, 284, + -214, -418, 94, -353, -353, -353, 100, 100, -302, -419, + 92, -294, -406, -375, 589, 589, -419, 27, -381, -380, + -296, 91, 82, 67, 584, 587, -419, -419, -419, 92, + -419, -419, -419, 93, 93, -419, -419, -419, -419, -419, + -419, -419, -419, -419, -419, -419, -419, -419, -419, -419, + -419, -419, -419, -419, -419, -419, -419, 92, -419, -177, + -179, -419, 81, -158, -230, 22, -98, 306, 308, -98, + -419, -419, -419, -419, -419, 92, -419, -419, 92, -419, + 92, -419, -419, -258, -419, 22, 22, 92, -419, -258, + -419, -258, -197, -229, -108, -107, -106, 616, -145, -210, + -243, 59, 81, 127, 94, 94, 94, 15, -418, -213, + 228, -307, -235, -255, -175, 389, -230, -419, -255, 93, + 27, 93, 739, 143, 93, -214, -125, -418, 280, -302, + 94, 94, -115, -118, -29, 92, 157, -255, -190, 67, + -145, -210, -419, 81, 597, 698, -92, -91, -88, 709, + 735, -210, -94, -94, -145, -145, -145, -419, -294, 251, + -419, -419, -108, 92, -105, -104, -294, -319, 585, 81, + 127, -267, -255, -307, -294, 93, -419, -418, -235, 93, + -239, -29, 91, -3, 280, -327, -378, -328, -329, -5, + -6, -354, -82, 585, -380, -358, -300, -296, 94, 100, + 93, 585, -419, -419, -90, 151, 707, 675, -155, 227, + -419, 92, -419, 92, -419, 92, -106, 92, 27, 590, + -419, -303, -176, -174, -294, 639, -397, -396, 581, -407, + -403, 123, 149, 105, -405, 677, 633, 133, 134, -82, + -145, 91, -419, -83, 295, 694, 228, -388, 586, -90, + 708, 653, 628, 653, 628, -150, -145, -145, -145, -104, + -418, -419, 92, 25, -320, -62, 650, -394, -395, 81, + -398, 395, 649, 670, 123, 94, 93, -255, 256, -301, + -382, 587, 148, -119, -419, 92, -419, 92, -419, -93, + -174, 646, -333, -158, -395, 81, -394, 81, 16, 15, + -4, 738, 93, 297, -90, 653, 628, -145, -145, -419, + -61, 28, -175, -393, 264, 259, 262, 34, -393, 100, + -4, -419, -419, 650, 258, 33, 123, -158, -178, -177, + -177, } var yyDef = [...]int{ @@ -9331,437 +9357,438 @@ var yyDef = [...]int{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 70, 72, 73, 880, 880, 880, 0, 880, 0, - 0, 880, -2, -2, 880, 1625, 0, 880, 0, 875, + 0, 880, -2, -2, 880, 1629, 0, 880, 0, 875, 0, -2, 797, 803, 0, 812, -2, 0, 0, 880, - 880, 2253, 2253, 875, 0, 0, 0, 0, 0, 880, - 880, 880, 880, 1630, 1483, 50, 880, 0, 85, 86, - 830, 831, 832, 65, 0, 2251, 881, 1, 3, 71, - 75, 0, 0, 0, 58, 1492, 0, 78, 0, 0, - 884, 0, 0, 1608, 880, 880, 0, 126, 127, 0, + 880, 2259, 2259, 875, 0, 0, 0, 0, 0, 880, + 880, 880, 880, 1634, 1487, 50, 880, 0, 85, 86, + 830, 831, 832, 65, 0, 2257, 881, 1, 3, 71, + 75, 0, 0, 0, 58, 1496, 0, 78, 0, 0, + 884, 0, 0, 1612, 880, 880, 0, 126, 127, 0, 0, 0, -2, 130, -2, 159, 160, 161, 0, 166, 607, 526, 578, 524, 563, -2, 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 529, - 401, 401, 0, 0, -2, 512, 512, 512, 1610, 0, + 401, 401, 0, 0, -2, 512, 512, 512, 1614, 0, 0, 0, 560, 463, 401, 401, 401, 0, 401, 401, 401, 401, 0, 0, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 1510, 165, 1626, 1623, 1624, 1783, 1784, 1785, 1786, - 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, - 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, 1806, - 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, - 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, - 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, - 1837, 1838, 1839, 1840, 1841, 1842, 1843, 1844, 1845, 1846, - 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, - 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, - 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, - 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, - 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, - 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, - 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, - 1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, - 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, - 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, - 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, - 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, - 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, - 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, - 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, - 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, - 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, - 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, - 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 2056, - 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, - 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, - 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, - 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, - 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, - 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, - 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, - 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, - 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, - 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, - 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, 2166, - 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, - 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, - 2187, 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, - 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, - 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, - 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, - 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, - 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, - 2247, 2248, 2249, 2250, 0, 1602, 0, 720, 980, 0, - 876, 877, 0, 786, 786, 0, 786, 786, 786, 786, - 0, 0, 0, 734, 0, 0, 0, 0, 783, 0, - 750, 751, 0, 783, 0, 757, 789, 0, 0, 764, - 786, 786, 767, 2254, 0, 2254, 2254, 1593, 0, 780, - 778, 792, 793, 42, 796, 799, 800, 801, 802, 805, - 0, 816, 819, 1619, 1620, 0, 821, 826, 843, 844, - 0, 45, 1136, 0, 1004, 0, 1012, -2, 1023, 1040, - 1041, 1042, 1043, 1044, 1046, 1047, 1048, 0, 0, 0, - 0, 1053, 1054, 0, 0, 0, 0, 0, 1117, 0, - 0, 0, 0, 1982, 1454, 0, 0, 1416, 1416, 1152, - 1416, 1416, 1418, 1418, 1418, 1835, 1974, 1983, 2160, 1796, - 1802, 1803, 1804, 2106, 2107, 2108, 2109, 2198, 2199, 2203, - 1898, 1791, 2173, 2174, 0, 2250, 1935, 1943, 1944, 1968, - 2070, 2183, 1814, 1963, 2033, 1895, 1917, 1918, 2051, 2052, - 1939, 1940, 1921, 2112, 2114, 2130, 2131, 2116, 2118, 2127, - 2133, 2138, 2117, 2129, 2134, 2147, 2151, 2154, 2155, 2156, - 2124, 2122, 2135, 2139, 2141, 2143, 2149, 2152, 2125, 2123, - 2136, 2140, 2142, 2144, 2150, 2153, 2111, 2115, 2119, 2128, - 2146, 2126, 2145, 2120, 2132, 2137, 2148, 2121, 2113, 1933, - 1936, 1924, 1925, 1927, 1929, 1934, 1941, 1947, 1926, 1946, - 1945, 0, 1922, 1923, 1928, 1938, 1942, 1930, 1931, 1932, - 1937, 1948, 1989, 1988, 1987, 2032, 1959, 2031, 0, 0, - 0, 0, 0, 1786, 1840, 1841, 2157, 1338, 1339, 1340, - 1341, 0, 0, 0, 0, 0, 0, 0, 291, 292, - 1467, 1468, 44, 1135, 1589, 1418, 1418, 1418, 1418, 1418, - 1418, 1075, 1076, 1077, 1078, 1079, 1105, 1106, 1112, 1113, - 2046, 2047, 2048, 2049, 1878, 2193, 1887, 1888, 2028, 2029, - 1900, 1901, 2224, 2225, -2, -2, -2, 232, 233, 234, - 235, 236, 237, 238, 239, 0, 1839, 2171, 2172, 228, - 0, 0, 296, 293, 294, 295, 1119, 1120, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 298, 299, 2253, 0, 853, 0, 0, 0, 0, 0, - 0, 1631, 1632, 1492, 0, 1484, 1483, 63, 0, 880, - -2, 0, 0, 0, 0, 47, 0, 52, 937, 883, - 77, 76, 1532, 1535, 0, 0, 0, 59, 1493, 67, - 69, 1494, 0, 885, 886, 0, 913, 917, 0, 0, - 0, 1609, 1608, 1608, 102, 0, 0, 103, 123, 124, - 125, 0, 0, 109, 110, 1595, 1596, 43, 0, 0, - 177, 178, 0, 1093, 428, 0, 173, 0, 421, 360, - 0, 1510, 0, 0, 0, 0, 0, 880, 0, 1603, - 154, 155, 162, 163, 164, 401, 401, 401, 575, 0, - 0, 165, 165, 533, 534, 535, 0, 0, -2, 426, - 0, 513, 0, 0, 415, 415, 419, 417, 418, 0, - 0, 0, 0, 0, 0, 0, 0, 552, 0, 553, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 668, - 0, 402, 0, 573, 574, 464, 0, 0, 0, 0, - 0, 0, 0, 0, 1611, 1612, 0, 550, 551, 0, - 0, 0, 401, 401, 0, 0, 0, 0, 401, 401, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 153, 1523, - 0, 0, 0, -2, 0, 712, 0, 0, 0, 1604, - 1604, 0, 719, 0, 0, 0, 724, 0, 0, 725, - 0, 783, 783, 781, 782, 727, 728, 729, 730, 786, - 0, 0, 410, 411, 412, 783, 786, 0, 786, 786, - 786, 786, 783, 783, 783, 786, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2254, 789, 786, 0, 758, - 0, 759, 760, 761, 762, 765, 766, 768, 2255, 2256, - 1621, 1622, 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, - 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, - 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, - 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, - 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1680, - 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690, - 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, - 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, - 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, - 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730, - 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, - 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, - 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, - 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, - 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, - 1781, 1782, 2254, 2254, 772, 776, 1594, 798, 804, 806, - 807, 0, 0, 817, 820, 837, 49, 1886, 825, 49, - 827, 828, 829, 855, 856, 861, 0, 0, 0, 0, - 867, 868, 869, 0, 0, 872, 873, 874, 0, 0, - 0, 0, 0, 1002, 0, 0, 1125, 1126, 1127, 1128, - 1129, 1130, 1131, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1024, 1025, 0, 0, 0, 1049, 1050, 1051, 1052, - 1055, 0, 1066, 0, 1068, 1463, -2, 0, 0, 0, - 1060, 1061, 0, 0, 0, 1614, 1614, 0, 0, 0, - 1455, 0, 0, 1150, 0, 1151, 1153, 1154, 1155, 0, - 1156, 1157, 890, 890, 890, 890, 890, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 890, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1614, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1614, 0, 0, 1614, 1614, 0, - 0, 220, 221, 222, 223, 224, 225, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 297, 240, 241, 242, 243, 244, 245, 300, 246, - 247, 248, 1135, 0, 0, 0, 46, 845, 846, 0, - 963, 1614, 0, 0, 896, 0, 1629, 57, 66, 68, - 1492, 61, 1492, 0, 900, 0, 0, -2, -2, 901, - 902, 906, 907, 908, 909, 910, 54, 2252, 55, 0, - 74, 0, 48, 0, 0, 1533, 0, 1536, 0, 0, - 0, 374, 1540, 0, 0, 1485, 1486, 1489, 0, 914, - 1980, 918, 0, 920, 921, 0, 0, 100, 0, 979, - 0, 0, 0, 111, 0, 113, 114, 0, 0, 0, - 385, 1597, 1598, 1599, -2, 408, 0, 385, 369, 308, - 309, 310, 360, 312, 360, 360, 360, 360, 374, 374, - 374, 374, 343, 344, 345, 346, 347, 0, 0, 329, - 360, 360, 360, 360, 350, 351, 352, 353, 354, 355, - 356, 357, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 362, 362, 362, 362, 362, 366, 366, 0, 1094, - 0, 389, 0, 1489, 0, 0, 1523, 1606, 1616, 0, - 0, 0, 1606, 132, 0, 0, 0, 576, 618, 527, - 564, 577, 0, 530, 531, -2, 0, 0, 512, 0, - 514, 0, 409, 0, -2, 0, 419, 0, 415, 419, - 416, 419, 407, 420, 554, 555, 556, 0, 558, 559, - 648, 949, 0, 0, 0, 0, 0, 654, 655, 656, - 0, 658, 659, 660, 661, 662, 663, 664, 665, 666, - 667, 565, 566, 567, 568, 569, 570, 571, 572, 0, - 0, 0, 0, 514, 0, 561, 0, 0, 465, 466, - 467, 0, 0, 470, 471, 472, 473, 0, 0, 476, - 477, 478, 966, 967, 479, 480, 505, 506, 507, 481, - 482, 483, 484, 485, 486, 487, 499, 500, 501, 502, - 503, 504, 488, 489, 490, 491, 492, 493, 496, 0, - 147, 1514, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1604, 0, - 0, 0, 0, 899, 981, 1627, 1628, 721, 0, 0, - 787, 788, 0, 413, 414, 786, 786, 731, 773, 0, - 786, 735, 774, 736, 738, 737, 739, 752, 753, 786, - 742, 784, 785, 743, 744, 745, 746, 747, 748, 749, - 769, 754, 755, 756, 790, 0, 794, 795, 770, 771, - 0, 0, 810, 811, 0, 818, 840, 838, 839, 841, - 833, 834, 835, 836, 0, 842, 0, 0, 858, 96, - 863, 864, 865, 866, 878, 871, 1137, 999, 1000, 1001, - 0, 1003, 1009, 0, 1121, 1123, 1007, 1008, 1011, 1005, - 1013, 1132, 1133, 1134, 0, 0, 0, 0, 0, 1017, - 1021, 1026, 1027, 1028, 1029, 1030, 0, 1031, 0, 1034, - 1035, 1036, 1037, 1038, 1039, 1045, 1431, 1432, 1433, 1064, - 301, 302, 0, 1065, 0, 0, 0, 0, 0, 0, - 0, 0, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, - 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, - 1396, 1397, 1136, 0, 1615, 0, 0, 0, 1461, 1458, - 0, 0, 0, 1417, 1419, 0, 0, 0, 891, 892, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1398, 1399, 1400, - 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, - 1411, 1412, 1413, 1414, 1415, 0, 0, 1434, 0, 0, - 0, 0, 0, 1454, 0, 1070, 1071, 1072, 0, 0, - 0, 0, 0, 0, 1196, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 142, 143, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1342, 1343, 1344, 1345, 41, 0, 0, 0, 0, 0, - 0, 0, 1465, 0, -2, -2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1367, - 0, 0, 0, 0, 0, 0, 1587, 0, 0, 848, - 849, 851, 0, 983, 0, 964, 0, 0, 854, 0, - 895, 0, 898, 60, 62, 904, 905, 0, 922, 911, - 903, 56, 51, 0, 0, 941, 1534, 1537, 1538, 374, - 1560, 0, 383, 383, 380, 1495, 1496, 0, 1488, 1490, - 1491, 79, 919, 915, 0, 997, 0, 0, 978, 0, - 925, 927, 928, 929, 961, 0, 932, 933, 0, 0, - 0, 0, 0, 98, 980, 104, 0, 112, 0, 0, - 117, 118, 105, 106, 107, 108, 0, 607, -2, 460, - 179, 181, 182, 183, 174, -2, 372, 370, 371, 311, - 374, 374, 337, 338, 339, 340, 341, 342, 0, 0, - 330, 331, 332, 333, 322, 0, 323, 324, 325, 364, - 0, 326, 327, 0, 328, 427, 0, 1497, 390, 391, - 393, 401, 0, 396, 397, 0, 401, 401, 0, 422, - 423, 0, 1489, 1514, 0, 0, 0, 1617, 1616, 1616, - 1616, 0, 167, 168, 169, 170, 171, 172, 643, 0, - 0, 619, 641, 642, 165, 0, 0, 175, 516, 515, - 0, 675, 0, 425, 0, 0, 419, 419, 404, 405, - 557, 0, 0, 650, 651, 652, 653, 0, 0, 0, - 543, 454, 0, 544, 545, 514, 516, 0, 0, 385, - 468, 469, 474, 475, 494, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 592, 593, 594, - 597, 599, 518, 603, 605, 596, 598, 600, 518, 604, - 606, 1511, 1512, 1513, 0, 0, 713, 0, 0, 451, - 94, 1605, 718, 722, 723, 783, 741, 775, 783, 733, - 740, 763, 808, 809, 814, 822, 823, 824, 862, 0, - 0, 0, 0, 870, 0, 0, 1010, 1122, 1124, 1014, - 0, 1018, 1022, 0, 0, 0, 0, 0, 1069, 1067, - 1465, 0, 0, 0, 1118, 0, 0, 1140, 1141, 0, - 0, 0, 0, 1459, 0, 0, 1148, 0, 1420, 1099, - 0, 0, 0, 0, 0, 1099, 1099, 1099, 1099, 1099, - 1099, 1099, 1099, 1099, 1099, 1483, 1175, 0, 0, 0, - 0, 0, 1180, 1181, 1182, 1183, 1184, 0, 1186, 0, - 1187, 0, 0, 0, 0, 1194, 1195, 1197, 0, 0, - 1200, 1201, 0, 1203, 0, 1205, 1206, 1207, 1208, 1209, - 1210, 0, 1212, 0, 1214, 1215, 1216, 0, 1218, 0, - 1220, 1221, 0, 1223, 0, 1225, 0, 1228, 0, 1231, - 0, 1234, 0, 1237, 0, 1240, 0, 1243, 0, 1246, - 0, 1249, 0, 1252, 0, 1255, 0, 1258, 0, 1261, - 0, 1264, 0, 1267, 0, 1270, 0, 1273, 1274, 1275, - 0, 1277, 0, 1279, 0, 1282, 1283, 0, 1285, 0, - 1288, 0, 1291, 0, 0, 1292, 0, 0, 0, 1296, - 0, 0, 0, 0, 1305, 1306, 1307, 1308, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1319, 1320, - 1321, 1322, 1323, 1324, 0, 1326, 0, 1100, 0, 0, - 1100, 0, 0, 0, 0, 0, 1138, 1614, 0, 1421, - 1422, 1423, 1424, 1425, 0, 0, 0, 0, 0, 0, - 1365, 1366, 1368, 0, 0, 1371, 0, 1373, 0, 1588, - 847, 850, 852, 935, 984, 985, 0, 0, 0, 0, - 965, 1613, 893, 894, 897, 943, 0, 1469, 0, 0, - 922, 997, 0, 923, 0, 53, 938, 0, 1542, 1541, - 1554, 1567, 383, 383, 377, 378, 384, 379, 381, 382, - 1487, 0, 1492, 0, 1581, 0, 0, 1570, 0, 0, - 0, 0, 0, 0, 0, 0, 968, 0, 0, 971, - 0, 0, 0, 0, 962, 933, 0, 934, 0, -2, - 0, 0, 92, 93, 0, 0, 0, 115, 116, 0, - 0, 122, 386, 387, 156, 165, 462, 180, 435, 0, - 0, 307, 373, 334, 335, 336, 0, 358, 0, 0, - 0, 0, 456, 128, 1501, 1500, 401, 401, 392, 0, - 395, 0, 0, 0, 1618, 361, 424, 0, 146, 0, - 0, 0, 0, 0, 152, 613, 0, 0, 620, 0, - 0, 0, 525, 0, 536, 537, 0, 647, -2, 709, - 389, 0, 403, 406, 950, 0, 0, 538, 0, 541, - 542, 455, 516, 547, 548, 562, 549, 497, 498, 495, - 0, 0, 1524, 1525, 1530, 1528, 1529, 133, 583, 585, - 589, 584, 588, 0, 0, 0, 520, 0, 520, 581, - 0, 451, 1497, 0, 717, 452, 453, 786, 786, 857, - 97, 0, 860, 0, 0, 0, 0, 1015, 1019, 1032, - 1033, 1426, 1452, 360, 360, 1439, 360, 366, 1442, 360, - 1444, 360, 1447, 360, 1450, 1451, 0, 0, 1062, 0, - 0, 0, 0, 1147, 1462, 0, 0, 1158, 1098, 1099, - 1099, 1099, 1099, 1099, 1164, 1165, 1166, 1167, 1168, 1169, - 1170, 1171, 1172, 1173, 1456, 0, 0, 0, 1179, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, - 145, 0, 0, 0, 0, 0, 0, 1376, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1093, - 1097, 0, 1101, 1102, 0, 0, 1328, 0, 0, 1346, - 0, 0, 0, 0, 0, 0, 0, 1466, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 986, 993, - 0, 993, 0, 993, 0, 0, 0, 1600, 1601, 1470, - 1471, 997, 1472, 912, 924, 942, 1560, 0, 1553, 0, - -2, 1562, 0, 0, 0, 1568, 375, 376, 916, 80, - 998, 83, 0, 1581, 1590, 0, 1578, 1583, 1585, 0, - 0, 0, 1574, 0, 997, 926, 957, 959, 0, 954, - 969, 970, 972, 0, 974, 0, 976, 977, 937, 931, - 0, 100, 0, 997, 997, 99, 0, 982, 119, 120, - 121, 461, 184, 189, 0, 0, 0, 194, 0, 196, - 0, 0, 0, 201, 202, 401, 401, 436, 0, 304, - 306, 0, 0, 187, 374, 0, 374, 0, 365, 367, - 0, 437, 457, 1498, 1499, 0, 0, 394, 398, 399, - 400, 0, 1607, 148, 0, 0, 0, 616, 0, 644, - 0, 0, 0, 0, 0, 0, 176, 517, 676, 677, - 678, 679, 680, 681, 682, 683, 684, 0, 401, 0, - 0, 0, 401, 401, 401, 0, 701, 388, 0, 0, - 672, 669, 539, 0, 218, 219, 226, 227, 229, 0, - 0, 0, 0, 0, 546, 937, 1515, 1516, 1517, 0, - 1527, 1531, 136, 0, 0, 0, 0, 591, 595, 601, - 0, 519, 602, 714, 715, 716, 95, 726, 732, 859, - 879, 1006, 1016, 1020, 0, 0, 0, 0, 1453, 1437, - 374, 1440, 1441, 1443, 1445, 1446, 1448, 1449, 1058, 1059, - 1063, 0, 1144, 0, 1146, 0, 1460, 0, 1159, 1160, - 1161, 1162, 1163, 1492, 0, 0, 0, 1178, 0, 0, - 0, 1189, 1188, 1190, 0, 1192, 1193, 1198, 1199, 1202, - 1204, 1211, 1213, 1217, 1219, 1222, 1224, 1226, 0, 1229, - 0, 1232, 0, 1235, 0, 1238, 0, 1241, 0, 1244, - 0, 1247, 0, 1250, 0, 1253, 0, 1256, 0, 1259, - 0, 1262, 0, 1265, 0, 1268, 0, 1271, 0, 1276, - 1278, 0, 1281, 1284, 1286, 0, 1289, 0, 1293, 0, - 1295, 1297, 1298, 0, 0, 0, 1309, 1310, 1311, 1312, - 1313, 1314, 1315, 1316, 1317, 1318, 1325, 0, 1091, 1327, - 1103, 1104, 1109, 1330, 0, 0, 0, 1333, 0, 0, - 0, 1337, 1139, 1348, 0, 1353, 0, 0, 1359, 0, - 1363, 0, 1369, 1370, 1372, 1374, 0, 0, 0, 0, - 0, 0, 0, 963, 944, 64, 1472, 1476, 0, 1547, - 1545, 1545, 1555, 1556, 0, 0, 1563, 0, 0, 0, - 0, 84, 0, 0, 1569, 0, 0, 1586, 0, 0, - 0, 0, 101, 1483, 951, 958, 0, 0, 952, 0, - 953, 973, 975, 930, 0, 997, 997, 90, 91, 0, - 190, 0, 192, 0, 195, 197, 198, 199, 205, 206, - 207, 200, 0, 0, 303, 305, 0, 0, 348, 359, - 349, 0, 0, 1502, 1503, 1504, 1505, 1506, 1507, 1508, - 1509, 937, 149, 150, 151, 608, 0, 618, 0, 939, - 0, 611, 0, 528, 0, 0, 0, 401, 401, 401, - 0, 0, 0, 0, 686, 0, 0, 649, 0, 657, - 0, 0, 0, 230, 231, 0, 1526, 582, 0, 134, - 135, 0, 0, 587, 521, 522, 1056, 0, 0, 0, - 1057, 1438, 0, 0, 0, 0, 0, 1457, 0, 0, - 0, 0, 1185, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1301, 0, 0, 0, 638, - 639, 0, 1377, 1096, 1483, 0, 1100, 1110, 1111, 0, - 1100, 1347, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 994, 0, 0, 0, 945, 946, 0, - 0, 0, 983, 1476, 1481, 0, 0, 1550, 0, 1543, - 1546, 1544, 1557, 0, 0, 1564, 0, 1566, 0, 1591, - 1592, 1584, 1579, 0, 1573, 1576, 1578, 1575, 1492, 955, - 0, 960, 0, 1483, 89, 0, 193, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 203, 204, 0, 0, - 363, 368, 0, 0, 0, 609, 0, 940, 621, 612, - 0, 699, 0, 703, 0, 0, 0, 706, 707, 708, - 685, 0, 689, 429, 673, 670, 671, 540, 0, 137, - 138, 0, 0, 0, 1427, 0, 1430, 1142, 1145, 1143, - 0, 1174, 1176, 1177, 1435, 1436, 1191, 1227, 1230, 1233, - 1236, 1239, 1242, 1245, 1248, 1251, 1254, 1257, 1260, 1263, - 1266, 1269, 1272, 1280, 1287, 1290, 1294, 1299, 0, 1302, - 0, 0, 1303, 0, 640, 1087, 0, 0, 1107, 1108, - 0, 1332, 1334, 1335, 1336, 1349, 0, 1354, 1355, 0, - 1360, 0, 1364, 1375, 0, 988, 995, 996, 0, 991, - 0, 992, 0, 936, 1481, 82, 1482, 1479, 0, 1477, - 1474, 1539, 0, 1548, 1549, 1558, 1559, 1565, 0, 0, - 1578, 0, 1572, 87, 0, 0, 0, 1492, 191, 0, - 210, 0, 617, 0, 620, 610, 697, 698, 0, 710, - 702, 704, 705, 687, -2, 1518, 0, 0, 0, 590, - 1428, 0, 0, 1304, 0, 636, 637, 1095, 1088, 0, - 1073, 1074, 1092, 1329, 1331, 0, 0, 0, 987, 947, - 948, 989, 990, 81, 0, 1478, 1115, 0, 1473, 0, - 1551, 1552, 1582, 0, 1571, 1577, 956, 963, 0, 88, - 442, 435, 1518, 0, 0, 0, 690, 691, 692, 693, - 694, 695, 696, 579, 1520, 139, 140, 0, 509, 510, - 511, 133, 0, 1149, 1300, 1089, 0, 0, 0, 0, - 0, 1350, 0, 1356, 0, 1361, 0, 1480, 0, 0, - 1475, 1580, 622, 0, 624, 0, -2, 430, 443, 0, - 185, 211, 212, 0, 0, 215, 216, 217, 208, 209, - 129, 0, 0, 711, 0, 1521, 1522, 0, 136, 0, - 0, 1080, 1081, 1082, 1083, 1085, 0, 0, 0, 0, - 1116, 1093, 623, 0, 0, 385, 0, 633, 431, 432, - 0, 438, 439, 440, 441, 213, 214, 645, 0, 0, - 508, 586, 1429, 0, 0, 1351, 0, 1357, 0, 1362, - 0, 625, 626, 634, 0, 433, 0, 434, 0, 0, - 0, 614, 0, 645, 1519, 1090, 1084, 1086, 0, 0, - 1114, 0, 635, 631, 444, 446, 447, 0, 0, 445, - 646, 615, 1352, 1358, 0, 448, 449, 450, 627, 628, - 629, 630, + 401, 1514, 165, 1630, 1627, 1628, 1787, 1788, 1789, 1790, + 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, + 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, + 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, + 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, + 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, + 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, + 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, + 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, + 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, + 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, + 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, + 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, + 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, + 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, + 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, + 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, + 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, + 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, + 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, + 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, + 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, + 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, + 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, + 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, + 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, + 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, + 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, + 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, + 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, + 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, + 2111, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, + 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, 2130, + 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, + 2141, 2142, 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, + 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, + 2161, 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, + 2171, 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, + 2181, 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, + 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, + 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2210, + 2211, 2212, 2213, 2214, 2215, 2216, 2217, 2218, 2219, 2220, + 2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, + 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, + 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, + 2251, 2252, 2253, 2254, 2255, 2256, 0, 1606, 0, 720, + 980, 0, 876, 877, 0, 786, 786, 0, 786, 786, + 786, 786, 0, 0, 0, 734, 0, 0, 0, 0, + 783, 0, 750, 751, 0, 783, 0, 757, 789, 0, + 0, 764, 786, 786, 767, 2260, 0, 2260, 2260, 1597, + 0, 780, 778, 792, 793, 42, 796, 799, 800, 801, + 802, 805, 0, 816, 819, 1623, 1624, 0, 821, 826, + 843, 844, 0, 45, 1140, 0, 1004, 0, 1015, -2, + 1026, 1043, 1044, 1045, 1046, 1047, 1049, 1050, 1051, 0, + 0, 0, 0, 1056, 1057, 0, 0, 0, 0, 0, + 1120, 0, 0, 0, 0, 1987, 1458, 0, 0, 1420, + 1420, 1156, 1420, 1420, 1422, 1422, 1422, 1840, 1979, 1988, + 2166, 1801, 1807, 1808, 1809, 2112, 2113, 2114, 2115, 2204, + 2205, 2209, 1903, 1796, 2179, 2180, 0, 2256, 1940, 1948, + 1949, 1973, 2075, 2189, 1819, 1968, 2038, 1900, 1922, 1923, + 2056, 2057, 1944, 1945, 1926, 2118, 2120, 2136, 2137, 2122, + 2124, 2133, 2139, 2144, 2123, 2135, 2140, 2153, 2157, 2160, + 2161, 2162, 2130, 2128, 2141, 2145, 2147, 2149, 2155, 2158, + 2131, 2129, 2142, 2146, 2148, 2150, 2156, 2159, 2117, 2121, + 2125, 2134, 2152, 2132, 2151, 2126, 2138, 2143, 2154, 2127, + 2119, 1938, 1941, 1929, 1930, 1932, 1934, 1939, 1946, 1952, + 1931, 1951, 1950, 0, 1927, 1928, 1933, 1943, 1947, 1935, + 1936, 1937, 1942, 1953, 1994, 1993, 1992, 2037, 1964, 2036, + 0, 0, 0, 0, 0, 1790, 1845, 1846, 2163, 1342, + 1343, 1344, 1345, 0, 0, 0, 0, 0, 0, 0, + 291, 292, 1471, 1472, 44, 1139, 1593, 1422, 1422, 1422, + 1422, 1422, 1422, 1078, 1079, 1080, 1081, 1082, 1108, 1109, + 1115, 1116, 2051, 2052, 2053, 2054, 1883, 2199, 1892, 1893, + 2033, 2034, 1905, 1906, 2230, 2231, -2, -2, -2, 232, + 233, 234, 235, 236, 237, 238, 239, 0, 1844, 2177, + 2178, 228, 0, 0, 296, 293, 294, 295, 1122, 1123, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 298, 299, 2259, 0, 853, 0, 0, 0, + 0, 0, 0, 1635, 1636, 1496, 0, 1488, 1487, 63, + 0, 880, -2, 0, 0, 0, 0, 47, 0, 52, + 937, 883, 77, 76, 1536, 1539, 0, 0, 0, 59, + 1497, 67, 69, 1498, 0, 885, 886, 0, 913, 917, + 0, 0, 0, 1613, 1612, 1612, 102, 0, 0, 103, + 123, 124, 125, 0, 0, 109, 110, 1599, 1600, 43, + 0, 0, 177, 178, 0, 1096, 428, 0, 173, 0, + 421, 360, 0, 1514, 0, 0, 0, 0, 0, 880, + 0, 1607, 154, 155, 162, 163, 164, 401, 401, 401, + 575, 0, 0, 165, 165, 533, 534, 535, 0, 0, + -2, 426, 0, 513, 0, 0, 415, 415, 419, 417, + 418, 0, 0, 0, 0, 0, 0, 0, 0, 552, + 0, 553, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 668, 0, 402, 0, 573, 574, 464, 0, 0, + 0, 0, 0, 0, 0, 0, 1615, 1616, 0, 550, + 551, 0, 0, 0, 401, 401, 0, 0, 0, 0, + 401, 401, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 153, 1527, 0, 0, 0, -2, 0, 712, 0, 0, + 0, 1608, 1608, 0, 719, 0, 0, 0, 724, 0, + 0, 725, 0, 783, 783, 781, 782, 727, 728, 729, + 730, 786, 0, 0, 410, 411, 412, 783, 786, 0, + 786, 786, 786, 786, 783, 783, 783, 786, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2260, 789, 786, + 0, 758, 0, 759, 760, 761, 762, 765, 766, 768, + 2261, 2262, 1625, 1626, 1637, 1638, 1639, 1640, 1641, 1642, + 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, + 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, + 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, + 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, + 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, + 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, + 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, + 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, + 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, + 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, + 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, + 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, + 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, + 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, + 1783, 1784, 1785, 1786, 2260, 2260, 772, 776, 1598, 798, + 804, 806, 807, 0, 0, 817, 820, 837, 49, 1891, + 825, 49, 827, 828, 829, 855, 856, 861, 0, 0, + 0, 0, 867, 868, 869, 0, 0, 872, 873, 874, + 0, 0, 0, 0, 0, 1002, 0, 0, 1128, 1129, + 1130, 1131, 1132, 1133, 1134, 1135, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1027, 1028, 0, 0, 0, 1052, + 1053, 1054, 1055, 1058, 0, 1069, 0, 1071, 1467, -2, + 0, 0, 0, 1063, 1064, 0, 0, 0, 1618, 1618, + 0, 0, 0, 1459, 0, 0, 1154, 0, 1155, 1157, + 1158, 1159, 0, 1160, 1161, 890, 890, 890, 890, 890, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 890, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1618, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1618, 0, 0, + 1618, 1618, 0, 0, 220, 221, 222, 223, 224, 225, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 297, 240, 241, 242, 243, 244, + 245, 300, 246, 247, 248, 1139, 0, 0, 0, 46, + 845, 846, 0, 963, 1618, 0, 0, 896, 0, 1633, + 57, 66, 68, 1496, 61, 1496, 0, 900, 0, 0, + -2, -2, 901, 902, 906, 907, 908, 909, 910, 54, + 2258, 55, 0, 74, 0, 48, 0, 0, 1537, 0, + 1540, 0, 0, 0, 374, 1544, 0, 0, 1489, 1490, + 1493, 0, 914, 1985, 918, 0, 920, 921, 0, 0, + 100, 0, 979, 0, 0, 0, 111, 0, 113, 114, + 0, 0, 0, 385, 1601, 1602, 1603, -2, 408, 0, + 385, 369, 308, 309, 310, 360, 312, 360, 360, 360, + 360, 374, 374, 374, 374, 343, 344, 345, 346, 347, + 0, 0, 329, 360, 360, 360, 360, 350, 351, 352, + 353, 354, 355, 356, 357, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 362, 362, 362, 362, 362, 366, + 366, 0, 1097, 0, 389, 0, 1493, 0, 0, 1527, + 1610, 1620, 0, 0, 0, 1610, 132, 0, 0, 0, + 576, 618, 527, 564, 577, 0, 530, 531, -2, 0, + 0, 512, 0, 514, 0, 409, 0, -2, 0, 419, + 0, 415, 419, 416, 419, 407, 420, 554, 555, 556, + 0, 558, 559, 648, 949, 0, 0, 0, 0, 0, + 654, 655, 656, 0, 658, 659, 660, 661, 662, 663, + 664, 665, 666, 667, 565, 566, 567, 568, 569, 570, + 571, 572, 0, 0, 0, 0, 514, 0, 561, 0, + 0, 465, 466, 467, 0, 0, 470, 471, 472, 473, + 0, 0, 476, 477, 478, 966, 967, 479, 480, 505, + 506, 507, 481, 482, 483, 484, 485, 486, 487, 499, + 500, 501, 502, 503, 504, 488, 489, 490, 491, 492, + 493, 496, 0, 147, 1518, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1608, 0, 0, 0, 0, 899, 981, 1631, 1632, + 721, 0, 0, 787, 788, 0, 413, 414, 786, 786, + 731, 773, 0, 786, 735, 774, 736, 738, 737, 739, + 752, 753, 786, 742, 784, 785, 743, 744, 745, 746, + 747, 748, 749, 769, 754, 755, 756, 790, 0, 794, + 795, 770, 771, 0, 0, 810, 811, 0, 818, 840, + 838, 839, 841, 833, 834, 835, 836, 0, 842, 0, + 0, 858, 96, 863, 864, 865, 866, 878, 871, 1141, + 999, 1000, 1001, 0, 1003, 1009, 0, 1124, 1126, 1007, + 1008, 1011, 0, 0, 0, 1005, 1016, 1136, 1137, 1138, + 0, 0, 0, 0, 0, 1020, 1024, 1029, 1030, 1031, + 1032, 1033, 0, 1034, 0, 1037, 1038, 1039, 1040, 1041, + 1042, 1048, 1435, 1436, 1437, 1067, 301, 302, 0, 1068, + 0, 0, 0, 0, 0, 0, 0, 0, 1382, 1383, + 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, + 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1140, 0, + 1619, 0, 0, 0, 1465, 1462, 0, 0, 0, 1421, + 1423, 0, 0, 0, 891, 892, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1402, 1403, 1404, 1405, 1406, 1407, 1408, + 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, + 1419, 0, 0, 1438, 0, 0, 0, 0, 0, 1458, + 0, 1073, 1074, 1075, 0, 0, 0, 0, 0, 0, + 1200, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 142, 143, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1346, 1347, 1348, 1349, + 41, 0, 0, 0, 0, 0, 0, 0, 1469, 0, + -2, -2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1371, 0, 0, 0, 0, + 0, 0, 1591, 0, 0, 848, 849, 851, 0, 983, + 0, 964, 0, 0, 854, 0, 895, 0, 898, 60, + 62, 904, 905, 0, 922, 911, 903, 56, 51, 0, + 0, 941, 1538, 1541, 1542, 374, 1564, 0, 383, 383, + 380, 1499, 1500, 0, 1492, 1494, 1495, 79, 919, 915, + 0, 997, 0, 0, 978, 0, 925, 927, 928, 929, + 961, 0, 932, 933, 0, 0, 0, 0, 0, 98, + 980, 104, 0, 112, 0, 0, 117, 118, 105, 106, + 107, 108, 0, 607, -2, 460, 179, 181, 182, 183, + 174, -2, 372, 370, 371, 311, 374, 374, 337, 338, + 339, 340, 341, 342, 0, 0, 330, 331, 332, 333, + 322, 0, 323, 324, 325, 364, 0, 326, 327, 0, + 328, 427, 0, 1501, 390, 391, 393, 401, 0, 396, + 397, 0, 401, 401, 0, 422, 423, 0, 1493, 1518, + 0, 0, 0, 1621, 1620, 1620, 1620, 0, 167, 168, + 169, 170, 171, 172, 643, 0, 0, 619, 641, 642, + 165, 0, 0, 175, 516, 515, 0, 675, 0, 425, + 0, 0, 419, 419, 404, 405, 557, 0, 0, 650, + 651, 652, 653, 0, 0, 0, 543, 454, 0, 544, + 545, 514, 516, 0, 0, 385, 468, 469, 474, 475, + 494, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 592, 593, 594, 597, 599, 518, 603, + 605, 596, 598, 600, 518, 604, 606, 1515, 1516, 1517, + 0, 0, 713, 0, 0, 451, 94, 1609, 718, 722, + 723, 783, 741, 775, 783, 733, 740, 763, 808, 809, + 814, 822, 823, 824, 862, 0, 0, 0, 0, 870, + 0, 0, 1010, 1125, 1127, 1012, 1013, 1014, 1017, 0, + 1021, 1025, 0, 0, 0, 0, 0, 1072, 1070, 1469, + 0, 0, 0, 1121, 0, 0, 1144, 1145, 0, 0, + 0, 0, 1463, 0, 0, 1152, 0, 1424, 1102, 0, + 0, 0, 0, 0, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1487, 1179, 0, 0, 0, 0, + 0, 1184, 1185, 1186, 1187, 1188, 0, 1190, 0, 1191, + 0, 0, 0, 0, 1198, 1199, 1201, 0, 0, 1204, + 1205, 0, 1207, 0, 1209, 1210, 1211, 1212, 1213, 1214, + 0, 1216, 0, 1218, 1219, 1220, 0, 1222, 0, 1224, + 1225, 0, 1227, 0, 1229, 0, 1232, 0, 1235, 0, + 1238, 0, 1241, 0, 1244, 0, 1247, 0, 1250, 0, + 1253, 0, 1256, 0, 1259, 0, 1262, 0, 1265, 0, + 1268, 0, 1271, 0, 1274, 0, 1277, 1278, 1279, 0, + 1281, 0, 1283, 0, 1286, 1287, 0, 1289, 0, 1292, + 0, 1295, 0, 0, 1296, 0, 0, 0, 1300, 0, + 0, 0, 0, 1309, 1310, 1311, 1312, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1323, 1324, 1325, + 1326, 1327, 1328, 0, 1330, 0, 1103, 0, 0, 1103, + 0, 0, 0, 0, 0, 1142, 1618, 0, 1425, 1426, + 1427, 1428, 1429, 0, 0, 0, 0, 0, 0, 1369, + 1370, 1372, 0, 0, 1375, 0, 1377, 0, 1592, 847, + 850, 852, 935, 984, 985, 0, 0, 0, 0, 965, + 1617, 893, 894, 897, 943, 0, 1473, 0, 0, 922, + 997, 0, 923, 0, 53, 938, 0, 1546, 1545, 1558, + 1571, 383, 383, 377, 378, 384, 379, 381, 382, 1491, + 0, 1496, 0, 1585, 0, 0, 1574, 0, 0, 0, + 0, 0, 0, 0, 0, 968, 0, 0, 971, 0, + 0, 0, 0, 962, 933, 0, 934, 0, -2, 0, + 0, 92, 93, 0, 0, 0, 115, 116, 0, 0, + 122, 386, 387, 156, 165, 462, 180, 435, 0, 0, + 307, 373, 334, 335, 336, 0, 358, 0, 0, 0, + 0, 456, 128, 1505, 1504, 401, 401, 392, 0, 395, + 0, 0, 0, 1622, 361, 424, 0, 146, 0, 0, + 0, 0, 0, 152, 613, 0, 0, 620, 0, 0, + 0, 525, 0, 536, 537, 0, 647, -2, 709, 389, + 0, 403, 406, 950, 0, 0, 538, 0, 541, 542, + 455, 516, 547, 548, 562, 549, 497, 498, 495, 0, + 0, 1528, 1529, 1534, 1532, 1533, 133, 583, 585, 589, + 584, 588, 0, 0, 0, 520, 0, 520, 581, 0, + 451, 1501, 0, 717, 452, 453, 786, 786, 857, 97, + 0, 860, 0, 0, 0, 0, 1018, 1022, 1035, 1036, + 1430, 1456, 360, 360, 1443, 360, 366, 1446, 360, 1448, + 360, 1451, 360, 1454, 1455, 0, 0, 1065, 0, 0, + 0, 0, 1151, 1466, 0, 0, 1162, 1101, 1102, 1102, + 1102, 1102, 1102, 1168, 1169, 1170, 1171, 1172, 1173, 1174, + 1175, 1176, 1177, 1460, 0, 0, 0, 1183, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 144, 145, + 0, 0, 0, 0, 0, 0, 1380, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1096, 1100, + 0, 1104, 1105, 0, 0, 1332, 0, 0, 1350, 0, + 0, 0, 0, 0, 0, 0, 1470, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 986, 993, 0, + 993, 0, 993, 0, 0, 0, 1604, 1605, 1474, 1475, + 997, 1476, 912, 924, 942, 1564, 0, 1557, 0, -2, + 1566, 0, 0, 0, 1572, 375, 376, 916, 80, 998, + 83, 0, 1585, 1594, 0, 1582, 1587, 1589, 0, 0, + 0, 1578, 0, 997, 926, 957, 959, 0, 954, 969, + 970, 972, 0, 974, 0, 976, 977, 937, 931, 0, + 100, 0, 997, 997, 99, 0, 982, 119, 120, 121, + 461, 184, 189, 0, 0, 0, 194, 0, 196, 0, + 0, 0, 201, 202, 401, 401, 436, 0, 304, 306, + 0, 0, 187, 374, 0, 374, 0, 365, 367, 0, + 437, 457, 1502, 1503, 0, 0, 394, 398, 399, 400, + 0, 1611, 148, 0, 0, 0, 616, 0, 644, 0, + 0, 0, 0, 0, 0, 176, 517, 676, 677, 678, + 679, 680, 681, 682, 683, 684, 0, 401, 0, 0, + 0, 401, 401, 401, 0, 701, 388, 0, 0, 672, + 669, 539, 0, 218, 219, 226, 227, 229, 0, 0, + 0, 0, 0, 546, 937, 1519, 1520, 1521, 0, 1531, + 1535, 136, 0, 0, 0, 0, 591, 595, 601, 0, + 519, 602, 714, 715, 716, 95, 726, 732, 859, 879, + 1006, 1019, 1023, 0, 0, 0, 0, 1457, 1441, 374, + 1444, 1445, 1447, 1449, 1450, 1452, 1453, 1061, 1062, 1066, + 0, 1148, 0, 1150, 0, 1464, 0, 1163, 1164, 1165, + 1166, 1167, 1496, 0, 0, 0, 1182, 0, 0, 0, + 1193, 1192, 1194, 0, 1196, 1197, 1202, 1203, 1206, 1208, + 1215, 1217, 1221, 1223, 1226, 1228, 1230, 0, 1233, 0, + 1236, 0, 1239, 0, 1242, 0, 1245, 0, 1248, 0, + 1251, 0, 1254, 0, 1257, 0, 1260, 0, 1263, 0, + 1266, 0, 1269, 0, 1272, 0, 1275, 0, 1280, 1282, + 0, 1285, 1288, 1290, 0, 1293, 0, 1297, 0, 1299, + 1301, 1302, 0, 0, 0, 1313, 1314, 1315, 1316, 1317, + 1318, 1319, 1320, 1321, 1322, 1329, 0, 1094, 1331, 1106, + 1107, 1112, 1334, 0, 0, 0, 1337, 0, 0, 0, + 1341, 1143, 1352, 0, 1357, 0, 0, 1363, 0, 1367, + 0, 1373, 1374, 1376, 1378, 0, 0, 0, 0, 0, + 0, 0, 963, 944, 64, 1476, 1480, 0, 1551, 1549, + 1549, 1559, 1560, 0, 0, 1567, 0, 0, 0, 0, + 84, 0, 0, 1573, 0, 0, 1590, 0, 0, 0, + 0, 101, 1487, 951, 958, 0, 0, 952, 0, 953, + 973, 975, 930, 0, 997, 997, 90, 91, 0, 190, + 0, 192, 0, 195, 197, 198, 199, 205, 206, 207, + 200, 0, 0, 303, 305, 0, 0, 348, 359, 349, + 0, 0, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, + 937, 149, 150, 151, 608, 0, 618, 0, 939, 0, + 611, 0, 528, 0, 0, 0, 401, 401, 401, 0, + 0, 0, 0, 686, 0, 0, 649, 0, 657, 0, + 0, 0, 230, 231, 0, 1530, 582, 0, 134, 135, + 0, 0, 587, 521, 522, 1059, 0, 0, 0, 1060, + 1442, 0, 0, 0, 0, 0, 1461, 0, 0, 0, + 0, 1189, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1305, 0, 0, 0, 638, 639, + 0, 1381, 1099, 1487, 0, 1103, 1113, 1114, 0, 1103, + 1351, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 994, 0, 0, 0, 945, 946, 0, 0, + 0, 983, 1480, 1485, 0, 0, 1554, 0, 1547, 1550, + 1548, 1561, 0, 0, 1568, 0, 1570, 0, 1595, 1596, + 1588, 1583, 0, 1577, 1580, 1582, 1579, 1496, 955, 0, + 960, 0, 1487, 89, 0, 193, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 203, 204, 0, 0, 363, + 368, 0, 0, 0, 609, 0, 940, 621, 612, 0, + 699, 0, 703, 0, 0, 0, 706, 707, 708, 685, + 0, 689, 429, 673, 670, 671, 540, 0, 137, 138, + 0, 0, 0, 1431, 0, 1434, 1146, 1149, 1147, 0, + 1178, 1180, 1181, 1439, 1440, 1195, 1231, 1234, 1237, 1240, + 1243, 1246, 1249, 1252, 1255, 1258, 1261, 1264, 1267, 1270, + 1273, 1276, 1284, 1291, 1294, 1298, 1303, 0, 1306, 0, + 0, 1307, 0, 640, 1090, 0, 0, 1110, 1111, 0, + 1336, 1338, 1339, 1340, 1353, 0, 1358, 1359, 0, 1364, + 0, 1368, 1379, 0, 988, 995, 996, 0, 991, 0, + 992, 0, 936, 1485, 82, 1486, 1483, 0, 1481, 1478, + 1543, 0, 1552, 1553, 1562, 1563, 1569, 0, 0, 1582, + 0, 1576, 87, 0, 0, 0, 1496, 191, 0, 210, + 0, 617, 0, 620, 610, 697, 698, 0, 710, 702, + 704, 705, 687, -2, 1522, 0, 0, 0, 590, 1432, + 0, 0, 1308, 0, 636, 637, 1098, 1091, 0, 1076, + 1077, 1095, 1333, 1335, 0, 0, 0, 987, 947, 948, + 989, 990, 81, 0, 1482, 1118, 0, 1477, 0, 1555, + 1556, 1586, 0, 1575, 1581, 956, 963, 0, 88, 442, + 435, 1522, 0, 0, 0, 690, 691, 692, 693, 694, + 695, 696, 579, 1524, 139, 140, 0, 509, 510, 511, + 133, 0, 1153, 1304, 1092, 0, 0, 0, 0, 0, + 1354, 0, 1360, 0, 1365, 0, 1484, 0, 0, 1479, + 1584, 622, 0, 624, 0, -2, 430, 443, 0, 185, + 211, 212, 0, 0, 215, 216, 217, 208, 209, 129, + 0, 0, 711, 0, 1525, 1526, 0, 136, 0, 0, + 1083, 1084, 1085, 1086, 1088, 0, 0, 0, 0, 1119, + 1096, 623, 0, 0, 385, 0, 633, 431, 432, 0, + 438, 439, 440, 441, 213, 214, 645, 0, 0, 508, + 586, 1433, 0, 0, 1355, 0, 1361, 0, 1366, 0, + 625, 626, 634, 0, 433, 0, 434, 0, 0, 0, + 614, 0, 645, 1523, 1093, 1087, 1089, 0, 0, 1117, + 0, 635, 631, 444, 446, 447, 0, 0, 445, 646, + 615, 1356, 1362, 0, 448, 449, 450, 627, 628, 629, + 630, } var yyTok1 = [...]int{ 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 147, 3, 3, 3, 175, 167, 3, - 88, 90, 172, 170, 89, 171, 225, 173, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 737, - 155, 154, 156, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 150, 3, 3, 3, 178, 170, 3, + 91, 93, 175, 173, 92, 174, 228, 176, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 740, + 158, 157, 159, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 177, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 180, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 143, 3, 178, + 3, 3, 3, 3, 146, 3, 181, } var yyTok2 = [...]int{ @@ -9773,19 +9800,19 @@ var yyTok2 = [...]int{ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 91, 92, 93, 94, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 144, 145, - 146, 148, 149, 150, 151, 152, 153, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 168, 169, 174, - 176, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 147, 148, 149, 151, 152, 153, 154, 155, 156, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 171, 172, 177, 179, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 226, 227, 228, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, @@ -9886,7 +9913,8 @@ var yyTok3 = [...]int{ 58045, 720, 58046, 721, 58047, 722, 58048, 723, 58049, 724, 58050, 725, 58051, 726, 58052, 727, 58053, 728, 58054, 729, 58055, 730, 58056, 731, 58057, 732, 58058, 733, 58059, 734, - 58060, 735, 58061, 736, 0, + 58060, 735, 58061, 736, 58062, 737, 58063, 738, 58064, 739, + 0, } var yyErrorMessages = [...]struct { @@ -10236,7 +10264,7 @@ yydefault: case 1: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:616 +//line sql.y:621 { stmt := yyDollar[2].statementUnion() // If the statement is empty and we have comments @@ -10250,46 +10278,46 @@ yydefault: } case 2: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:629 +//line sql.y:634 { } case 3: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:630 +//line sql.y:635 { } case 4: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:634 +//line sql.y:639 { yyLOCAL = yyDollar[1].selStmtUnion() } yyVAL.union = yyLOCAL case 40: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:673 +//line sql.y:678 { setParseTree(yylex, nil) } case 41: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:679 +//line sql.y:684 { yyLOCAL = NewVariableExpression(yyDollar[1].str, SingleAt) } yyVAL.union = yyLOCAL case 42: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:685 +//line sql.y:690 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } case 43: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:691 +//line sql.y:696 { yyLOCAL = NewVariableExpression(string(yyDollar[1].str), SingleAt) } @@ -10297,7 +10325,7 @@ yydefault: case 44: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:695 +//line sql.y:700 { yyLOCAL = NewVariableExpression(string(yyDollar[1].str), DoubleAt) } @@ -10305,7 +10333,7 @@ yydefault: case 45: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:701 +//line sql.y:706 { yyLOCAL = &OtherAdmin{} } @@ -10313,7 +10341,7 @@ yydefault: case 46: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:707 +//line sql.y:712 { yyLOCAL = &Load{} } @@ -10321,7 +10349,7 @@ yydefault: case 47: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *With -//line sql.y:713 +//line sql.y:718 { yyLOCAL = &With{CTEs: yyDollar[2].ctesUnion(), Recursive: false} } @@ -10329,7 +10357,7 @@ yydefault: case 48: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *With -//line sql.y:717 +//line sql.y:722 { yyLOCAL = &With{CTEs: yyDollar[3].ctesUnion(), Recursive: true} } @@ -10337,7 +10365,7 @@ yydefault: case 49: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *With -//line sql.y:722 +//line sql.y:727 { yyLOCAL = nil } @@ -10345,14 +10373,14 @@ yydefault: case 50: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *With -//line sql.y:726 +//line sql.y:731 { yyLOCAL = yyDollar[1].withUnion() } yyVAL.union = yyLOCAL case 51: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:732 +//line sql.y:737 { yySLICE := (*[]*CommonTableExpr)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].cteUnion()) @@ -10360,7 +10388,7 @@ yydefault: case 52: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*CommonTableExpr -//line sql.y:736 +//line sql.y:741 { yyLOCAL = []*CommonTableExpr{yyDollar[1].cteUnion()} } @@ -10368,7 +10396,7 @@ yydefault: case 53: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *CommonTableExpr -//line sql.y:742 +//line sql.y:747 { yyLOCAL = &CommonTableExpr{ID: yyDollar[1].identifierCS, Columns: yyDollar[2].columnsUnion(), Subquery: yyDollar[4].subqueryUnion()} } @@ -10376,7 +10404,7 @@ yydefault: case 54: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:748 +//line sql.y:753 { yyLOCAL = yyDollar[2].selStmtUnion() } @@ -10384,7 +10412,7 @@ yydefault: case 55: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:752 +//line sql.y:757 { yyLOCAL = yyDollar[2].selStmtUnion() } @@ -10392,7 +10420,7 @@ yydefault: case 56: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:756 +//line sql.y:761 { setLockInSelect(yyDollar[2].selStmtUnion(), yyDollar[3].lockUnion()) yyLOCAL = yyDollar[2].selStmtUnion() @@ -10401,7 +10429,7 @@ yydefault: case 57: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:779 +//line sql.y:784 { yyDollar[1].selStmtUnion().SetOrderBy(yyDollar[2].orderByUnion()) yyDollar[1].selStmtUnion().SetLimit(yyDollar[3].limitUnion()) @@ -10411,7 +10439,7 @@ yydefault: case 58: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:785 +//line sql.y:790 { yyDollar[1].selStmtUnion().SetLimit(yyDollar[2].limitUnion()) yyLOCAL = yyDollar[1].selStmtUnion() @@ -10420,7 +10448,7 @@ yydefault: case 59: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:790 +//line sql.y:795 { yyDollar[1].selStmtUnion().SetOrderBy(yyDollar[2].orderByUnion()) yyDollar[1].selStmtUnion().SetLimit(yyDollar[3].limitUnion()) @@ -10430,7 +10458,7 @@ yydefault: case 60: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:796 +//line sql.y:801 { yyDollar[2].selStmtUnion().SetWith(yyDollar[1].withUnion()) yyDollar[2].selStmtUnion().SetOrderBy(yyDollar[3].orderByUnion()) @@ -10441,7 +10469,7 @@ yydefault: case 61: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:803 +//line sql.y:808 { yyDollar[2].selStmtUnion().SetWith(yyDollar[1].withUnion()) yyDollar[2].selStmtUnion().SetLimit(yyDollar[3].limitUnion()) @@ -10451,7 +10479,7 @@ yydefault: case 62: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:809 +//line sql.y:814 { yyDollar[2].selStmtUnion().SetWith(yyDollar[1].withUnion()) yyDollar[2].selStmtUnion().SetOrderBy(yyDollar[3].orderByUnion()) @@ -10461,14 +10489,14 @@ yydefault: yyVAL.union = yyLOCAL case 63: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:816 +//line sql.y:821 { yyDollar[2].selStmtUnion().SetWith(yyDollar[1].withUnion()) } case 64: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:820 +//line sql.y:825 { yyLOCAL = NewSelect(Comments(yyDollar[2].strs), SelectExprs{&Nextval{Expr: yyDollar[5].exprUnion()}}, []string{yyDollar[3].str} /*options*/, nil, TableExprs{&AliasedTableExpr{Expr: yyDollar[7].tableName}}, nil /*where*/, nil /*groupBy*/, nil /*having*/, nil) } @@ -10476,7 +10504,7 @@ yydefault: case 65: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:826 +//line sql.y:831 { yyLOCAL = yyDollar[1].selStmtUnion() } @@ -10484,7 +10512,7 @@ yydefault: case 66: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:830 +//line sql.y:835 { yyLOCAL = &Union{Left: yyDollar[1].selStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].selStmtUnion()} } @@ -10492,7 +10520,7 @@ yydefault: case 67: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:834 +//line sql.y:839 { yyLOCAL = &Union{Left: yyDollar[1].selStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].selStmtUnion()} } @@ -10500,7 +10528,7 @@ yydefault: case 68: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:838 +//line sql.y:843 { yyLOCAL = &Union{Left: yyDollar[1].selStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].selStmtUnion()} } @@ -10508,7 +10536,7 @@ yydefault: case 69: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:842 +//line sql.y:847 { yyLOCAL = &Union{Left: yyDollar[1].selStmtUnion(), Distinct: yyDollar[2].booleanUnion(), Right: yyDollar[3].selStmtUnion()} } @@ -10516,7 +10544,7 @@ yydefault: case 70: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:848 +//line sql.y:853 { yyLOCAL = yyDollar[1].selStmtUnion() } @@ -10524,7 +10552,7 @@ yydefault: case 71: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:852 +//line sql.y:857 { setLockInSelect(yyDollar[1].selStmtUnion(), yyDollar[2].lockUnion()) yyLOCAL = yyDollar[1].selStmtUnion() @@ -10533,7 +10561,7 @@ yydefault: case 72: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:857 +//line sql.y:862 { yyLOCAL = yyDollar[1].selStmtUnion() } @@ -10541,7 +10569,7 @@ yydefault: case 73: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:861 +//line sql.y:866 { yyLOCAL = yyDollar[1].selStmtUnion() } @@ -10549,7 +10577,7 @@ yydefault: case 74: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:867 +//line sql.y:872 { yyLOCAL = yyDollar[2].selStmtUnion() } @@ -10557,7 +10585,7 @@ yydefault: case 75: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:871 +//line sql.y:876 { yyDollar[1].selStmtUnion().SetInto(yyDollar[2].selectIntoUnion()) yyLOCAL = yyDollar[1].selStmtUnion() @@ -10566,7 +10594,7 @@ yydefault: case 76: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:876 +//line sql.y:881 { yyDollar[1].selStmtUnion().SetInto(yyDollar[2].selectIntoUnion()) yyDollar[1].selStmtUnion().SetLock(yyDollar[3].lockUnion()) @@ -10576,7 +10604,7 @@ yydefault: case 77: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:882 +//line sql.y:887 { yyDollar[1].selStmtUnion().SetInto(yyDollar[3].selectIntoUnion()) yyDollar[1].selStmtUnion().SetLock(yyDollar[2].lockUnion()) @@ -10586,7 +10614,7 @@ yydefault: case 78: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:888 +//line sql.y:893 { yyDollar[1].selStmtUnion().SetInto(yyDollar[2].selectIntoUnion()) yyLOCAL = yyDollar[1].selStmtUnion() @@ -10595,7 +10623,7 @@ yydefault: case 79: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:895 +//line sql.y:900 { yyLOCAL = &Stream{Comments: Comments(yyDollar[2].strs).Parsed(), SelectExpr: yyDollar[3].selectExprUnion(), Table: yyDollar[5].tableName} } @@ -10603,7 +10631,7 @@ yydefault: case 80: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:901 +//line sql.y:906 { yyLOCAL = &VStream{Comments: Comments(yyDollar[2].strs).Parsed(), SelectExpr: yyDollar[3].selectExprUnion(), Table: yyDollar[5].tableName, Where: NewWhere(WhereClause, yyDollar[6].exprUnion()), Limit: yyDollar[7].limitUnion()} } @@ -10611,7 +10639,7 @@ yydefault: case 81: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:909 +//line sql.y:914 { yyLOCAL = NewSelect(Comments(yyDollar[2].strs), yyDollar[4].selectExprsUnion() /*SelectExprs*/, yyDollar[3].strs /*options*/, yyDollar[5].selectIntoUnion() /*into*/, yyDollar[6].tableExprsUnion() /*from*/, NewWhere(WhereClause, yyDollar[7].exprUnion()), yyDollar[8].groupByUnion(), NewWhere(HavingClause, yyDollar[9].exprUnion()), yyDollar[10].namedWindowsUnion()) } @@ -10619,7 +10647,7 @@ yydefault: case 82: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL SelectStatement -//line sql.y:913 +//line sql.y:918 { yyLOCAL = NewSelect(Comments(yyDollar[2].strs), yyDollar[4].selectExprsUnion() /*SelectExprs*/, yyDollar[3].strs /*options*/, nil, yyDollar[5].tableExprsUnion() /*from*/, NewWhere(WhereClause, yyDollar[6].exprUnion()), yyDollar[7].groupByUnion(), NewWhere(HavingClause, yyDollar[8].exprUnion()), yyDollar[9].namedWindowsUnion()) } @@ -10627,7 +10655,7 @@ yydefault: case 83: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:919 +//line sql.y:924 { // insert_data returns a *Insert pre-filled with Columns & Values ins := yyDollar[6].insUnion() @@ -10643,7 +10671,7 @@ yydefault: case 84: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:931 +//line sql.y:936 { cols := make(Columns, 0, len(yyDollar[7].updateExprsUnion())) vals := make(ValTuple, 0, len(yyDollar[8].updateExprsUnion())) @@ -10657,7 +10685,7 @@ yydefault: case 85: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL InsertAction -//line sql.y:943 +//line sql.y:948 { yyLOCAL = InsertAct } @@ -10665,7 +10693,7 @@ yydefault: case 86: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL InsertAction -//line sql.y:947 +//line sql.y:952 { yyLOCAL = ReplaceAct } @@ -10673,7 +10701,7 @@ yydefault: case 87: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Statement -//line sql.y:953 +//line sql.y:958 { yyLOCAL = &Update{With: yyDollar[1].withUnion(), Comments: Comments(yyDollar[3].strs).Parsed(), Ignore: yyDollar[4].ignoreUnion(), TableExprs: yyDollar[5].tableExprsUnion(), Exprs: yyDollar[7].updateExprsUnion(), Where: NewWhere(WhereClause, yyDollar[8].exprUnion()), OrderBy: yyDollar[9].orderByUnion(), Limit: yyDollar[10].limitUnion()} } @@ -10681,7 +10709,7 @@ yydefault: case 88: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL Statement -//line sql.y:959 +//line sql.y:964 { yyLOCAL = &Delete{With: yyDollar[1].withUnion(), Comments: Comments(yyDollar[3].strs).Parsed(), Ignore: yyDollar[4].ignoreUnion(), TableExprs: TableExprs{&AliasedTableExpr{Expr: yyDollar[6].tableName, As: yyDollar[7].identifierCS}}, Partitions: yyDollar[8].partitionsUnion(), Where: NewWhere(WhereClause, yyDollar[9].exprUnion()), OrderBy: yyDollar[10].orderByUnion(), Limit: yyDollar[11].limitUnion()} } @@ -10689,7 +10717,7 @@ yydefault: case 89: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Statement -//line sql.y:963 +//line sql.y:968 { yyLOCAL = &Delete{With: yyDollar[1].withUnion(), Comments: Comments(yyDollar[3].strs).Parsed(), Ignore: yyDollar[4].ignoreUnion(), Targets: yyDollar[6].tableNamesUnion(), TableExprs: yyDollar[8].tableExprsUnion(), Where: NewWhere(WhereClause, yyDollar[9].exprUnion())} } @@ -10697,7 +10725,7 @@ yydefault: case 90: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:967 +//line sql.y:972 { yyLOCAL = &Delete{With: yyDollar[1].withUnion(), Comments: Comments(yyDollar[3].strs).Parsed(), Ignore: yyDollar[4].ignoreUnion(), Targets: yyDollar[5].tableNamesUnion(), TableExprs: yyDollar[7].tableExprsUnion(), Where: NewWhere(WhereClause, yyDollar[8].exprUnion())} } @@ -10705,32 +10733,32 @@ yydefault: case 91: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:971 +//line sql.y:976 { yyLOCAL = &Delete{With: yyDollar[1].withUnion(), Comments: Comments(yyDollar[3].strs).Parsed(), Ignore: yyDollar[4].ignoreUnion(), Targets: yyDollar[5].tableNamesUnion(), TableExprs: yyDollar[7].tableExprsUnion(), Where: NewWhere(WhereClause, yyDollar[8].exprUnion())} } yyVAL.union = yyLOCAL case 92: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:976 +//line sql.y:981 { } case 93: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:977 +//line sql.y:982 { } case 94: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableNames -//line sql.y:981 +//line sql.y:986 { yyLOCAL = TableNames{yyDollar[1].tableName} } yyVAL.union = yyLOCAL case 95: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:985 +//line sql.y:990 { yySLICE := (*TableNames)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableName) @@ -10738,14 +10766,14 @@ yydefault: case 96: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableNames -//line sql.y:991 +//line sql.y:996 { yyLOCAL = TableNames{yyDollar[1].tableName} } yyVAL.union = yyLOCAL case 97: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:995 +//line sql.y:1000 { yySLICE := (*TableNames)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableName) @@ -10753,14 +10781,14 @@ yydefault: case 98: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableNames -//line sql.y:1001 +//line sql.y:1006 { yyLOCAL = TableNames{yyDollar[1].tableName} } yyVAL.union = yyLOCAL case 99: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1005 +//line sql.y:1010 { yySLICE := (*TableNames)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableName) @@ -10768,7 +10796,7 @@ yydefault: case 100: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Partitions -//line sql.y:1010 +//line sql.y:1015 { yyLOCAL = nil } @@ -10776,7 +10804,7 @@ yydefault: case 101: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Partitions -//line sql.y:1014 +//line sql.y:1019 { yyLOCAL = yyDollar[3].partitionsUnion() } @@ -10784,7 +10812,7 @@ yydefault: case 102: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:1020 +//line sql.y:1025 { yyLOCAL = NewSetStatement(Comments(yyDollar[2].strs).Parsed(), yyDollar[3].setExprsUnion()) } @@ -10792,14 +10820,14 @@ yydefault: case 103: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SetExprs -//line sql.y:1026 +//line sql.y:1031 { yyLOCAL = SetExprs{yyDollar[1].setExprUnion()} } yyVAL.union = yyLOCAL case 104: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1030 +//line sql.y:1035 { yySLICE := (*SetExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].setExprUnion()) @@ -10807,7 +10835,7 @@ yydefault: case 105: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1036 +//line sql.y:1041 { yyLOCAL = &SetExpr{Var: yyDollar[1].variableUnion(), Expr: NewStrLiteral("on")} } @@ -10815,7 +10843,7 @@ yydefault: case 106: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1040 +//line sql.y:1045 { yyLOCAL = &SetExpr{Var: yyDollar[1].variableUnion(), Expr: NewStrLiteral("off")} } @@ -10823,7 +10851,7 @@ yydefault: case 107: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1044 +//line sql.y:1049 { yyLOCAL = &SetExpr{Var: yyDollar[1].variableUnion(), Expr: yyDollar[3].exprUnion()} } @@ -10831,7 +10859,7 @@ yydefault: case 108: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1048 +//line sql.y:1053 { yyLOCAL = &SetExpr{Var: NewSetVariable(string(yyDollar[1].str), SessionScope), Expr: yyDollar[2].exprUnion()} } @@ -10839,7 +10867,7 @@ yydefault: case 109: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:1054 +//line sql.y:1059 { yyLOCAL = NewSetVariable(string(yyDollar[1].str), SessionScope) } @@ -10847,7 +10875,7 @@ yydefault: case 110: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:1058 +//line sql.y:1063 { yyLOCAL = yyDollar[1].variableUnion() } @@ -10855,7 +10883,7 @@ yydefault: case 111: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Variable -//line sql.y:1062 +//line sql.y:1067 { yyLOCAL = NewSetVariable(string(yyDollar[2].str), yyDollar[1].scopeUnion()) } @@ -10863,7 +10891,7 @@ yydefault: case 112: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:1068 +//line sql.y:1073 { yyLOCAL = NewSetStatement(Comments(yyDollar[2].strs).Parsed(), UpdateSetExprsScope(yyDollar[5].setExprsUnion(), yyDollar[3].scopeUnion())) } @@ -10871,7 +10899,7 @@ yydefault: case 113: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:1072 +//line sql.y:1077 { yyLOCAL = NewSetStatement(Comments(yyDollar[2].strs).Parsed(), yyDollar[4].setExprsUnion()) } @@ -10879,14 +10907,14 @@ yydefault: case 114: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SetExprs -//line sql.y:1078 +//line sql.y:1083 { yyLOCAL = SetExprs{yyDollar[1].setExprUnion()} } yyVAL.union = yyLOCAL case 115: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1082 +//line sql.y:1087 { yySLICE := (*SetExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].setExprUnion()) @@ -10894,7 +10922,7 @@ yydefault: case 116: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1088 +//line sql.y:1093 { yyLOCAL = &SetExpr{Var: NewSetVariable(TransactionIsolationStr, NextTxScope), Expr: NewStrLiteral(yyDollar[3].str)} } @@ -10902,7 +10930,7 @@ yydefault: case 117: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1092 +//line sql.y:1097 { yyLOCAL = &SetExpr{Var: NewSetVariable(TransactionReadOnlyStr, NextTxScope), Expr: NewStrLiteral("off")} } @@ -10910,39 +10938,39 @@ yydefault: case 118: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1096 +//line sql.y:1101 { yyLOCAL = &SetExpr{Var: NewSetVariable(TransactionReadOnlyStr, NextTxScope), Expr: NewStrLiteral("on")} } yyVAL.union = yyLOCAL case 119: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1102 +//line sql.y:1107 { yyVAL.str = RepeatableReadStr } case 120: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1106 +//line sql.y:1111 { yyVAL.str = ReadCommittedStr } case 121: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1110 +//line sql.y:1115 { yyVAL.str = ReadUncommittedStr } case 122: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1114 +//line sql.y:1119 { yyVAL.str = SerializableStr } case 123: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Scope -//line sql.y:1120 +//line sql.y:1125 { yyLOCAL = SessionScope } @@ -10950,7 +10978,7 @@ yydefault: case 124: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Scope -//line sql.y:1124 +//line sql.y:1129 { yyLOCAL = SessionScope } @@ -10958,7 +10986,7 @@ yydefault: case 125: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Scope -//line sql.y:1128 +//line sql.y:1133 { yyLOCAL = GlobalScope } @@ -10966,7 +10994,7 @@ yydefault: case 126: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:1134 +//line sql.y:1139 { yyDollar[1].createTableUnion().TableSpec = yyDollar[2].tableSpecUnion() yyDollar[1].createTableUnion().FullyParsed = true @@ -10976,7 +11004,7 @@ yydefault: case 127: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:1140 +//line sql.y:1145 { // Create table [name] like [name] yyDollar[1].createTableUnion().OptLike = yyDollar[2].optLikeUnion() @@ -10987,7 +11015,7 @@ yydefault: case 128: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:1147 +//line sql.y:1152 { indexDef := yyDollar[1].alterTableUnion().AlterOptions[0].(*AddIndexDefinition).IndexDefinition indexDef.Columns = yyDollar[3].indexColumnsUnion() @@ -11000,7 +11028,7 @@ yydefault: case 129: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Statement -//line sql.y:1156 +//line sql.y:1161 { yyLOCAL = &CreateView{ViewName: yyDollar[8].tableName, Comments: Comments(yyDollar[2].strs).Parsed(), IsReplace: yyDollar[3].booleanUnion(), Algorithm: yyDollar[4].str, Definer: yyDollar[5].definerUnion(), Security: yyDollar[6].str, Columns: yyDollar[9].columnsUnion(), Select: yyDollar[11].selStmtUnion(), CheckOption: yyDollar[12].str} } @@ -11008,7 +11036,7 @@ yydefault: case 130: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:1160 +//line sql.y:1165 { yyDollar[1].createDatabaseUnion().FullyParsed = true yyDollar[1].createDatabaseUnion().CreateOptions = yyDollar[2].databaseOptionsUnion() @@ -11018,7 +11046,7 @@ yydefault: case 131: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:1167 +//line sql.y:1172 { yyLOCAL = false } @@ -11026,33 +11054,33 @@ yydefault: case 132: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:1171 +//line sql.y:1176 { yyLOCAL = true } yyVAL.union = yyLOCAL case 133: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1176 +//line sql.y:1181 { yyVAL.identifierCI = NewIdentifierCI("") } case 134: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1180 +//line sql.y:1185 { yyVAL.identifierCI = yyDollar[2].identifierCI } case 135: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1186 +//line sql.y:1191 { yyVAL.identifierCI = yyDollar[1].identifierCI } case 136: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []VindexParam -//line sql.y:1191 +//line sql.y:1196 { var v []VindexParam yyLOCAL = v @@ -11061,7 +11089,7 @@ yydefault: case 137: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []VindexParam -//line sql.y:1196 +//line sql.y:1201 { yyLOCAL = yyDollar[2].vindexParamsUnion() } @@ -11069,7 +11097,7 @@ yydefault: case 138: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []VindexParam -//line sql.y:1202 +//line sql.y:1207 { yyLOCAL = make([]VindexParam, 0, 4) yyLOCAL = append(yyLOCAL, yyDollar[1].vindexParam) @@ -11077,21 +11105,21 @@ yydefault: yyVAL.union = yyLOCAL case 139: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1207 +//line sql.y:1212 { yySLICE := (*[]VindexParam)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].vindexParam) } case 140: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1213 +//line sql.y:1218 { yyVAL.vindexParam = VindexParam{Key: yyDollar[1].identifierCI, Val: yyDollar[3].str} } case 141: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*JSONObjectParam -//line sql.y:1218 +//line sql.y:1223 { yyLOCAL = nil } @@ -11099,7 +11127,7 @@ yydefault: case 142: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*JSONObjectParam -//line sql.y:1222 +//line sql.y:1227 { yyLOCAL = yyDollar[1].jsonObjectParamsUnion() } @@ -11107,28 +11135,28 @@ yydefault: case 143: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*JSONObjectParam -//line sql.y:1228 +//line sql.y:1233 { yyLOCAL = []*JSONObjectParam{yyDollar[1].jsonObjectParam} } yyVAL.union = yyLOCAL case 144: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1232 +//line sql.y:1237 { yySLICE := (*[]*JSONObjectParam)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].jsonObjectParam) } case 145: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1238 +//line sql.y:1243 { yyVAL.jsonObjectParam = &JSONObjectParam{Key: yyDollar[1].exprUnion(), Value: yyDollar[3].exprUnion()} } case 146: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *CreateTable -//line sql.y:1244 +//line sql.y:1249 { yyLOCAL = &CreateTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[6].tableName, IfNotExists: yyDollar[5].booleanUnion(), Temp: yyDollar[3].booleanUnion()} setDDL(yylex, yyLOCAL) @@ -11137,7 +11165,7 @@ yydefault: case 147: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1251 +//line sql.y:1256 { yyLOCAL = &AlterTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[4].tableName} setDDL(yylex, yyLOCAL) @@ -11146,7 +11174,7 @@ yydefault: case 148: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1258 +//line sql.y:1263 { yyLOCAL = &AlterTable{Table: yyDollar[7].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[4].identifierCI}, Options: yyDollar[5].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) @@ -11155,7 +11183,7 @@ yydefault: case 149: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1263 +//line sql.y:1268 { yyLOCAL = &AlterTable{Table: yyDollar[8].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[5].identifierCI, Type: IndexTypeFullText}, Options: yyDollar[6].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) @@ -11164,7 +11192,7 @@ yydefault: case 150: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1268 +//line sql.y:1273 { yyLOCAL = &AlterTable{Table: yyDollar[8].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[5].identifierCI, Type: IndexTypeSpatial}, Options: yyDollar[6].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) @@ -11173,7 +11201,7 @@ yydefault: case 151: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1273 +//line sql.y:1278 { yyLOCAL = &AlterTable{Table: yyDollar[8].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[5].identifierCI, Type: IndexTypeUnique}, Options: yyDollar[6].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) @@ -11182,7 +11210,7 @@ yydefault: case 152: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *CreateDatabase -//line sql.y:1280 +//line sql.y:1285 { yyLOCAL = &CreateDatabase{Comments: Comments(yyDollar[4].strs).Parsed(), DBName: yyDollar[6].identifierCS, IfNotExists: yyDollar[5].booleanUnion()} setDDL(yylex, yyLOCAL) @@ -11191,7 +11219,7 @@ yydefault: case 153: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *AlterDatabase -//line sql.y:1287 +//line sql.y:1292 { yyLOCAL = &AlterDatabase{} setDDL(yylex, yyLOCAL) @@ -11200,7 +11228,7 @@ yydefault: case 156: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *TableSpec -//line sql.y:1298 +//line sql.y:1303 { yyLOCAL = yyDollar[2].tableSpecUnion() yyLOCAL.Options = yyDollar[4].tableOptionsUnion() @@ -11210,7 +11238,7 @@ yydefault: case 157: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1305 +//line sql.y:1310 { yyLOCAL = nil } @@ -11218,7 +11246,7 @@ yydefault: case 158: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1309 +//line sql.y:1314 { yyLOCAL = yyDollar[1].databaseOptionsUnion() } @@ -11226,7 +11254,7 @@ yydefault: case 159: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1315 +//line sql.y:1320 { yyLOCAL = []DatabaseOption{yyDollar[1].databaseOption} } @@ -11234,7 +11262,7 @@ yydefault: case 160: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1319 +//line sql.y:1324 { yyLOCAL = []DatabaseOption{yyDollar[1].databaseOption} } @@ -11242,28 +11270,28 @@ yydefault: case 161: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1323 +//line sql.y:1328 { yyLOCAL = []DatabaseOption{yyDollar[1].databaseOption} } yyVAL.union = yyLOCAL case 162: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1327 +//line sql.y:1332 { yySLICE := (*[]DatabaseOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].databaseOption) } case 163: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1331 +//line sql.y:1336 { yySLICE := (*[]DatabaseOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].databaseOption) } case 164: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1335 +//line sql.y:1340 { yySLICE := (*[]DatabaseOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].databaseOption) @@ -11271,7 +11299,7 @@ yydefault: case 165: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:1341 +//line sql.y:1346 { yyLOCAL = false } @@ -11279,51 +11307,51 @@ yydefault: case 166: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:1345 +//line sql.y:1350 { yyLOCAL = true } yyVAL.union = yyLOCAL case 167: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1351 +//line sql.y:1356 { yyVAL.databaseOption = DatabaseOption{Type: CharacterSetType, Value: string(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } case 168: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1355 +//line sql.y:1360 { yyVAL.databaseOption = DatabaseOption{Type: CharacterSetType, Value: encodeSQLString(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } case 169: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1361 +//line sql.y:1366 { yyVAL.databaseOption = DatabaseOption{Type: CollateType, Value: string(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } case 170: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1365 +//line sql.y:1370 { yyVAL.databaseOption = DatabaseOption{Type: CollateType, Value: encodeSQLString(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } case 171: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1371 +//line sql.y:1376 { yyVAL.databaseOption = DatabaseOption{Type: EncryptionType, Value: string(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } case 172: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1375 +//line sql.y:1380 { yyVAL.databaseOption = DatabaseOption{Type: EncryptionType, Value: encodeSQLString(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } case 173: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *OptLike -//line sql.y:1381 +//line sql.y:1386 { yyLOCAL = &OptLike{LikeTable: yyDollar[2].tableName} } @@ -11331,7 +11359,7 @@ yydefault: case 174: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *OptLike -//line sql.y:1385 +//line sql.y:1390 { yyLOCAL = &OptLike{LikeTable: yyDollar[3].tableName} } @@ -11339,14 +11367,14 @@ yydefault: case 175: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColumnDefinition -//line sql.y:1391 +//line sql.y:1396 { yyLOCAL = []*ColumnDefinition{yyDollar[1].columnDefinitionUnion()} } yyVAL.union = yyLOCAL case 176: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1395 +//line sql.y:1400 { yySLICE := (*[]*ColumnDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].columnDefinitionUnion()) @@ -11354,7 +11382,7 @@ yydefault: case 177: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *TableSpec -//line sql.y:1401 +//line sql.y:1406 { yyLOCAL = &TableSpec{} yyLOCAL.AddColumn(yyDollar[1].columnDefinitionUnion()) @@ -11363,7 +11391,7 @@ yydefault: case 178: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *TableSpec -//line sql.y:1406 +//line sql.y:1411 { yyLOCAL = &TableSpec{} yyLOCAL.AddConstraint(yyDollar[1].constraintDefinitionUnion()) @@ -11371,39 +11399,39 @@ yydefault: yyVAL.union = yyLOCAL case 179: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1411 +//line sql.y:1416 { yyVAL.tableSpecUnion().AddColumn(yyDollar[3].columnDefinitionUnion()) } case 180: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1415 +//line sql.y:1420 { yyVAL.tableSpecUnion().AddColumn(yyDollar[3].columnDefinitionUnion()) yyVAL.tableSpecUnion().AddConstraint(yyDollar[4].constraintDefinitionUnion()) } case 181: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1420 +//line sql.y:1425 { yyVAL.tableSpecUnion().AddIndex(yyDollar[3].indexDefinitionUnion()) } case 182: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1424 +//line sql.y:1429 { yyVAL.tableSpecUnion().AddConstraint(yyDollar[3].constraintDefinitionUnion()) } case 183: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1428 +//line sql.y:1433 { yyVAL.tableSpecUnion().AddConstraint(yyDollar[3].constraintDefinitionUnion()) } case 184: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColumnDefinition -//line sql.y:1439 +//line sql.y:1444 { yyDollar[2].columnType.Options = yyDollar[4].columnTypeOptionsUnion() if yyDollar[2].columnType.Options.Collate == "" { @@ -11416,7 +11444,7 @@ yydefault: case 185: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL *ColumnDefinition -//line sql.y:1448 +//line sql.y:1453 { yyDollar[2].columnType.Options = yyDollar[9].columnTypeOptionsUnion() yyDollar[2].columnType.Options.As = yyDollar[7].exprUnion() @@ -11427,20 +11455,20 @@ yydefault: yyVAL.union = yyLOCAL case 186: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1457 +//line sql.y:1462 { yyVAL.str = "" } case 187: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1461 +//line sql.y:1466 { yyVAL.str = "" } case 188: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1470 +//line sql.y:1475 { yyLOCAL = &ColumnTypeOptions{Null: nil, Default: nil, OnUpdate: nil, Autoincrement: false, KeyOpt: ColKeyNone, Comment: nil, As: nil, Invisible: nil, Format: UnspecifiedFormat, EngineAttribute: nil, SecondaryEngineAttribute: nil} } @@ -11448,7 +11476,7 @@ yydefault: case 189: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1474 +//line sql.y:1479 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11457,7 +11485,7 @@ yydefault: case 190: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1479 +//line sql.y:1484 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11466,7 +11494,7 @@ yydefault: case 191: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1484 +//line sql.y:1489 { yyDollar[1].columnTypeOptionsUnion().Default = yyDollar[4].exprUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11475,7 +11503,7 @@ yydefault: case 192: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1489 +//line sql.y:1494 { yyDollar[1].columnTypeOptionsUnion().Default = yyDollar[3].exprUnion() yyDollar[1].columnTypeOptionsUnion().DefaultLiteral = true @@ -11485,7 +11513,7 @@ yydefault: case 193: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1495 +//line sql.y:1500 { yyDollar[1].columnTypeOptionsUnion().OnUpdate = yyDollar[4].exprUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11494,7 +11522,7 @@ yydefault: case 194: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1500 +//line sql.y:1505 { yyDollar[1].columnTypeOptionsUnion().Autoincrement = true yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11503,7 +11531,7 @@ yydefault: case 195: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1505 +//line sql.y:1510 { yyDollar[1].columnTypeOptionsUnion().Comment = NewStrLiteral(yyDollar[3].str) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11512,7 +11540,7 @@ yydefault: case 196: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1510 +//line sql.y:1515 { yyDollar[1].columnTypeOptionsUnion().KeyOpt = yyDollar[2].colKeyOptUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11520,14 +11548,14 @@ yydefault: yyVAL.union = yyLOCAL case 197: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1515 +//line sql.y:1520 { yyDollar[1].columnTypeOptionsUnion().Collate = encodeSQLString(yyDollar[3].str) } case 198: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1519 +//line sql.y:1524 { yyDollar[1].columnTypeOptionsUnion().Collate = string(yyDollar[3].identifierCI.String()) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11535,14 +11563,14 @@ yydefault: yyVAL.union = yyLOCAL case 199: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1524 +//line sql.y:1529 { yyDollar[1].columnTypeOptionsUnion().Format = yyDollar[3].columnFormatUnion() } case 200: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1528 +//line sql.y:1533 { yyDollar[1].columnTypeOptionsUnion().SRID = NewIntLiteral(yyDollar[3].str) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11551,7 +11579,7 @@ yydefault: case 201: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1533 +//line sql.y:1538 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11560,7 +11588,7 @@ yydefault: case 202: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1538 +//line sql.y:1543 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11568,20 +11596,20 @@ yydefault: yyVAL.union = yyLOCAL case 203: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1543 +//line sql.y:1548 { yyDollar[1].columnTypeOptionsUnion().EngineAttribute = NewStrLiteral(yyDollar[4].str) } case 204: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1547 +//line sql.y:1552 { yyDollar[1].columnTypeOptionsUnion().SecondaryEngineAttribute = NewStrLiteral(yyDollar[4].str) } case 205: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnFormat -//line sql.y:1553 +//line sql.y:1558 { yyLOCAL = FixedFormat } @@ -11589,7 +11617,7 @@ yydefault: case 206: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnFormat -//line sql.y:1557 +//line sql.y:1562 { yyLOCAL = DynamicFormat } @@ -11597,7 +11625,7 @@ yydefault: case 207: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnFormat -//line sql.y:1561 +//line sql.y:1566 { yyLOCAL = DefaultFormat } @@ -11605,7 +11633,7 @@ yydefault: case 208: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnStorage -//line sql.y:1567 +//line sql.y:1572 { yyLOCAL = VirtualStorage } @@ -11613,7 +11641,7 @@ yydefault: case 209: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnStorage -//line sql.y:1571 +//line sql.y:1576 { yyLOCAL = StoredStorage } @@ -11621,7 +11649,7 @@ yydefault: case 210: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1576 +//line sql.y:1581 { yyLOCAL = &ColumnTypeOptions{} } @@ -11629,7 +11657,7 @@ yydefault: case 211: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1580 +//line sql.y:1585 { yyDollar[1].columnTypeOptionsUnion().Storage = yyDollar[2].columnStorageUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11638,7 +11666,7 @@ yydefault: case 212: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1585 +//line sql.y:1590 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11647,7 +11675,7 @@ yydefault: case 213: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1590 +//line sql.y:1595 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11656,7 +11684,7 @@ yydefault: case 214: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1595 +//line sql.y:1600 { yyDollar[1].columnTypeOptionsUnion().Comment = NewStrLiteral(yyDollar[3].str) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11665,7 +11693,7 @@ yydefault: case 215: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1600 +//line sql.y:1605 { yyDollar[1].columnTypeOptionsUnion().KeyOpt = yyDollar[2].colKeyOptUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11674,7 +11702,7 @@ yydefault: case 216: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1605 +//line sql.y:1610 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11683,7 +11711,7 @@ yydefault: case 217: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1610 +//line sql.y:1615 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() @@ -11692,7 +11720,7 @@ yydefault: case 218: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1617 +//line sql.y:1622 { yyLOCAL = yyDollar[1].exprUnion() } @@ -11700,7 +11728,7 @@ yydefault: case 220: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1624 +//line sql.y:1629 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("current_timestamp"), Fsp: yyDollar[2].integerUnion()} } @@ -11708,7 +11736,7 @@ yydefault: case 221: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1628 +//line sql.y:1633 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("localtime"), Fsp: yyDollar[2].integerUnion()} } @@ -11716,7 +11744,7 @@ yydefault: case 222: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1632 +//line sql.y:1637 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("localtimestamp"), Fsp: yyDollar[2].integerUnion()} } @@ -11724,7 +11752,7 @@ yydefault: case 223: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1636 +//line sql.y:1641 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("utc_timestamp"), Fsp: yyDollar[2].integerUnion()} } @@ -11732,7 +11760,7 @@ yydefault: case 224: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1640 +//line sql.y:1645 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("now"), Fsp: yyDollar[2].integerUnion()} } @@ -11740,7 +11768,7 @@ yydefault: case 225: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1644 +//line sql.y:1649 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("sysdate"), Fsp: yyDollar[2].integerUnion()} } @@ -11748,7 +11776,7 @@ yydefault: case 228: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1654 +//line sql.y:1659 { yyLOCAL = &NullVal{} } @@ -11756,7 +11784,7 @@ yydefault: case 230: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1661 +//line sql.y:1666 { yyLOCAL = yyDollar[2].exprUnion() } @@ -11764,7 +11792,7 @@ yydefault: case 231: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1665 +//line sql.y:1670 { yyLOCAL = &UnaryExpr{Operator: UMinusOp, Expr: yyDollar[2].exprUnion()} } @@ -11772,7 +11800,7 @@ yydefault: case 232: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1671 +//line sql.y:1676 { yyLOCAL = yyDollar[1].exprUnion() } @@ -11780,7 +11808,7 @@ yydefault: case 233: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1675 +//line sql.y:1680 { yyLOCAL = yyDollar[1].exprUnion() } @@ -11788,7 +11816,7 @@ yydefault: case 234: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1679 +//line sql.y:1684 { yyLOCAL = yyDollar[1].boolValUnion() } @@ -11796,7 +11824,7 @@ yydefault: case 235: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1683 +//line sql.y:1688 { yyLOCAL = NewHexLiteral(yyDollar[1].str) } @@ -11804,7 +11832,7 @@ yydefault: case 236: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1687 +//line sql.y:1692 { yyLOCAL = NewHexNumLiteral(yyDollar[1].str) } @@ -11812,7 +11840,7 @@ yydefault: case 237: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1691 +//line sql.y:1696 { yyLOCAL = NewBitLiteral(yyDollar[1].str) } @@ -11820,7 +11848,7 @@ yydefault: case 238: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1695 +//line sql.y:1700 { yyLOCAL = NewBitLiteral("0b" + yyDollar[1].str) } @@ -11828,7 +11856,7 @@ yydefault: case 239: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1699 +//line sql.y:1704 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } @@ -11836,7 +11864,7 @@ yydefault: case 240: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1703 +//line sql.y:1708 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewBitLiteral("0b" + yyDollar[2].str)} } @@ -11844,7 +11872,7 @@ yydefault: case 241: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1707 +//line sql.y:1712 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewHexNumLiteral(yyDollar[2].str)} } @@ -11852,7 +11880,7 @@ yydefault: case 242: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1711 +//line sql.y:1716 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewBitLiteral(yyDollar[2].str)} } @@ -11860,7 +11888,7 @@ yydefault: case 243: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1715 +//line sql.y:1720 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewHexLiteral(yyDollar[2].str)} } @@ -11868,7 +11896,7 @@ yydefault: case 244: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1719 +//line sql.y:1724 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: yyDollar[2].exprUnion()} } @@ -11876,7 +11904,7 @@ yydefault: case 245: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1723 +//line sql.y:1728 { arg := parseBindVariable(yylex, yyDollar[2].str[1:]) yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: arg} @@ -11885,7 +11913,7 @@ yydefault: case 246: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1728 +//line sql.y:1733 { yyLOCAL = NewDateLiteral(yyDollar[2].str) } @@ -11893,7 +11921,7 @@ yydefault: case 247: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1732 +//line sql.y:1737 { yyLOCAL = NewTimeLiteral(yyDollar[2].str) } @@ -11901,267 +11929,267 @@ yydefault: case 248: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1736 +//line sql.y:1741 { yyLOCAL = NewTimestampLiteral(yyDollar[2].str) } yyVAL.union = yyLOCAL case 249: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1742 +//line sql.y:1747 { yyVAL.str = Armscii8Str } case 250: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1746 +//line sql.y:1751 { yyVAL.str = ASCIIStr } case 251: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1750 +//line sql.y:1755 { yyVAL.str = Big5Str } case 252: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1754 +//line sql.y:1759 { yyVAL.str = UBinaryStr } case 253: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1758 +//line sql.y:1763 { yyVAL.str = Cp1250Str } case 254: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1762 +//line sql.y:1767 { yyVAL.str = Cp1251Str } case 255: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1766 +//line sql.y:1771 { yyVAL.str = Cp1256Str } case 256: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1770 +//line sql.y:1775 { yyVAL.str = Cp1257Str } case 257: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1774 +//line sql.y:1779 { yyVAL.str = Cp850Str } case 258: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1778 +//line sql.y:1783 { yyVAL.str = Cp852Str } case 259: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1782 +//line sql.y:1787 { yyVAL.str = Cp866Str } case 260: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1786 +//line sql.y:1791 { yyVAL.str = Cp932Str } case 261: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1790 +//line sql.y:1795 { yyVAL.str = Dec8Str } case 262: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1794 +//line sql.y:1799 { yyVAL.str = EucjpmsStr } case 263: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1798 +//line sql.y:1803 { yyVAL.str = EuckrStr } case 264: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1802 +//line sql.y:1807 { yyVAL.str = Gb18030Str } case 265: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1806 +//line sql.y:1811 { yyVAL.str = Gb2312Str } case 266: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1810 +//line sql.y:1815 { yyVAL.str = GbkStr } case 267: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1814 +//line sql.y:1819 { yyVAL.str = Geostd8Str } case 268: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1818 +//line sql.y:1823 { yyVAL.str = GreekStr } case 269: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1822 +//line sql.y:1827 { yyVAL.str = HebrewStr } case 270: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1826 +//line sql.y:1831 { yyVAL.str = Hp8Str } case 271: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1830 +//line sql.y:1835 { yyVAL.str = Keybcs2Str } case 272: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1834 +//line sql.y:1839 { yyVAL.str = Koi8rStr } case 273: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1838 +//line sql.y:1843 { yyVAL.str = Koi8uStr } case 274: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1842 +//line sql.y:1847 { yyVAL.str = Latin1Str } case 275: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1846 +//line sql.y:1851 { yyVAL.str = Latin2Str } case 276: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1850 +//line sql.y:1855 { yyVAL.str = Latin5Str } case 277: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1854 +//line sql.y:1859 { yyVAL.str = Latin7Str } case 278: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1858 +//line sql.y:1863 { yyVAL.str = MacceStr } case 279: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1862 +//line sql.y:1867 { yyVAL.str = MacromanStr } case 280: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1866 +//line sql.y:1871 { yyVAL.str = SjisStr } case 281: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1870 +//line sql.y:1875 { yyVAL.str = Swe7Str } case 282: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1874 +//line sql.y:1879 { yyVAL.str = Tis620Str } case 283: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1878 +//line sql.y:1883 { yyVAL.str = Ucs2Str } case 284: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1882 +//line sql.y:1887 { yyVAL.str = UjisStr } case 285: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1886 +//line sql.y:1891 { yyVAL.str = Utf16Str } case 286: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1890 +//line sql.y:1895 { yyVAL.str = Utf16leStr } case 287: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1894 +//line sql.y:1899 { yyVAL.str = Utf32Str } case 288: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1898 +//line sql.y:1903 { yyVAL.str = Utf8mb3Str } case 289: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1902 +//line sql.y:1907 { yyVAL.str = Utf8mb4Str } case 290: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1906 +//line sql.y:1911 { yyVAL.str = Utf8mb3Str } case 293: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1916 +//line sql.y:1921 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } @@ -12169,7 +12197,7 @@ yydefault: case 294: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1920 +//line sql.y:1925 { yyLOCAL = NewFloatLiteral(yyDollar[1].str) } @@ -12177,7 +12205,7 @@ yydefault: case 295: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1924 +//line sql.y:1929 { yyLOCAL = NewDecimalLiteral(yyDollar[1].str) } @@ -12185,7 +12213,7 @@ yydefault: case 296: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1930 +//line sql.y:1935 { yyLOCAL = yyDollar[1].exprUnion() } @@ -12193,7 +12221,7 @@ yydefault: case 297: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1934 +//line sql.y:1939 { yyLOCAL = AppendString(yyDollar[1].exprUnion(), yyDollar[2].str) } @@ -12201,7 +12229,7 @@ yydefault: case 298: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1940 +//line sql.y:1945 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } @@ -12209,7 +12237,7 @@ yydefault: case 299: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1944 +//line sql.y:1949 { yyLOCAL = &UnaryExpr{Operator: NStringOp, Expr: NewStrLiteral(yyDollar[1].str)} } @@ -12217,7 +12245,7 @@ yydefault: case 300: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:1948 +//line sql.y:1953 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewStrLiteral(yyDollar[2].str)} } @@ -12225,7 +12253,7 @@ yydefault: case 301: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1954 +//line sql.y:1959 { yyLOCAL = yyDollar[1].exprUnion() } @@ -12233,7 +12261,7 @@ yydefault: case 302: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:1958 +//line sql.y:1963 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } @@ -12241,7 +12269,7 @@ yydefault: case 303: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:1964 +//line sql.y:1969 { yyLOCAL = ColKeyPrimary } @@ -12249,7 +12277,7 @@ yydefault: case 304: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:1968 +//line sql.y:1973 { yyLOCAL = ColKeyUnique } @@ -12257,7 +12285,7 @@ yydefault: case 305: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:1972 +//line sql.y:1977 { yyLOCAL = ColKeyUniqueKey } @@ -12265,14 +12293,14 @@ yydefault: case 306: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:1976 +//line sql.y:1981 { yyLOCAL = ColKey } yyVAL.union = yyLOCAL case 307: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1982 +//line sql.y:1987 { yyVAL.columnType = yyDollar[1].columnType yyVAL.columnType.Unsigned = yyDollar[2].booleanUnion() @@ -12280,74 +12308,74 @@ yydefault: } case 311: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1993 +//line sql.y:1998 { yyVAL.columnType = yyDollar[1].columnType yyVAL.columnType.Length = yyDollar[2].intPtrUnion() } case 312: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1998 +//line sql.y:2003 { yyVAL.columnType = yyDollar[1].columnType } case 313: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2004 +//line sql.y:2009 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 314: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2008 +//line sql.y:2013 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 315: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2012 +//line sql.y:2017 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 316: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2016 +//line sql.y:2021 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 317: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2020 +//line sql.y:2025 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 318: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2024 +//line sql.y:2029 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 319: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2028 +//line sql.y:2033 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 320: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2032 +//line sql.y:2037 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 321: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2036 +//line sql.y:2041 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 322: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2042 +//line sql.y:2047 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -12355,7 +12383,7 @@ yydefault: } case 323: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2048 +//line sql.y:2053 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -12363,7 +12391,7 @@ yydefault: } case 324: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2054 +//line sql.y:2059 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -12371,7 +12399,7 @@ yydefault: } case 325: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2060 +//line sql.y:2065 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -12379,7 +12407,7 @@ yydefault: } case 326: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2066 +//line sql.y:2071 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -12387,7 +12415,7 @@ yydefault: } case 327: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2072 +//line sql.y:2077 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -12395,7 +12423,7 @@ yydefault: } case 328: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2078 +//line sql.y:2083 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -12403,43 +12431,43 @@ yydefault: } case 329: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2086 +//line sql.y:2091 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 330: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2090 +//line sql.y:2095 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 331: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2094 +//line sql.y:2099 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 332: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2098 +//line sql.y:2103 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 333: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2102 +//line sql.y:2107 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 334: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2108 +//line sql.y:2113 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} } case 335: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2112 +//line sql.y:2117 { // CHAR BYTE is an alias for binary. See also: // https://dev.mysql.com/doc/refman/8.0/en/string-type-syntax.html @@ -12447,153 +12475,153 @@ yydefault: } case 336: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2118 +//line sql.y:2123 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} } case 337: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2122 +//line sql.y:2127 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 338: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2126 +//line sql.y:2131 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 339: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2130 +//line sql.y:2135 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} } case 340: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2134 +//line sql.y:2139 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} } case 341: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2138 +//line sql.y:2143 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} } case 342: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2142 +//line sql.y:2147 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} } case 343: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2146 +//line sql.y:2151 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 344: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2150 +//line sql.y:2155 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 345: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2154 +//line sql.y:2159 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 346: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2158 +//line sql.y:2163 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 347: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2162 +//line sql.y:2167 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 348: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2166 +//line sql.y:2171 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].columnCharset} } case 349: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2171 +//line sql.y:2176 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].columnCharset} } case 350: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2177 +//line sql.y:2182 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 351: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2181 +//line sql.y:2186 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 352: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2185 +//line sql.y:2190 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 353: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2189 +//line sql.y:2194 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 354: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2193 +//line sql.y:2198 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 355: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2197 +//line sql.y:2202 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 356: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2201 +//line sql.y:2206 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 357: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2205 +//line sql.y:2210 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 358: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2211 +//line sql.y:2216 { yyVAL.strs = make([]string, 0, 4) yyVAL.strs = append(yyVAL.strs, encodeSQLString(yyDollar[1].str)) } case 359: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2216 +//line sql.y:2221 { yyVAL.strs = append(yyDollar[1].strs, encodeSQLString(yyDollar[3].str)) } case 360: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *int -//line sql.y:2221 +//line sql.y:2226 { yyLOCAL = nil } @@ -12601,20 +12629,20 @@ yydefault: case 361: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *int -//line sql.y:2225 +//line sql.y:2230 { yyLOCAL = ptr.Of(convertStringToInt(yyDollar[2].str)) } yyVAL.union = yyLOCAL case 362: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2230 +//line sql.y:2235 { yyVAL.LengthScaleOption = LengthScaleOption{} } case 363: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2234 +//line sql.y:2239 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), @@ -12623,13 +12651,13 @@ yydefault: } case 364: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2243 +//line sql.y:2248 { yyVAL.LengthScaleOption = yyDollar[1].LengthScaleOption } case 365: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2247 +//line sql.y:2252 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), @@ -12637,13 +12665,13 @@ yydefault: } case 366: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2254 +//line sql.y:2259 { yyVAL.LengthScaleOption = LengthScaleOption{} } case 367: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2258 +//line sql.y:2263 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), @@ -12651,7 +12679,7 @@ yydefault: } case 368: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2264 +//line sql.y:2269 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), @@ -12661,7 +12689,7 @@ yydefault: case 369: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2272 +//line sql.y:2277 { yyLOCAL = false } @@ -12669,7 +12697,7 @@ yydefault: case 370: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2276 +//line sql.y:2281 { yyLOCAL = true } @@ -12677,7 +12705,7 @@ yydefault: case 371: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2280 +//line sql.y:2285 { yyLOCAL = false } @@ -12685,7 +12713,7 @@ yydefault: case 372: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2285 +//line sql.y:2290 { yyLOCAL = false } @@ -12693,66 +12721,66 @@ yydefault: case 373: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2289 +//line sql.y:2294 { yyLOCAL = true } yyVAL.union = yyLOCAL case 374: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2294 +//line sql.y:2299 { yyVAL.columnCharset = ColumnCharset{} } case 375: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2298 +//line sql.y:2303 { yyVAL.columnCharset = ColumnCharset{Name: string(yyDollar[2].identifierCI.String()), Binary: yyDollar[3].booleanUnion()} } case 376: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2302 +//line sql.y:2307 { yyVAL.columnCharset = ColumnCharset{Name: encodeSQLString(yyDollar[2].str), Binary: yyDollar[3].booleanUnion()} } case 377: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2306 +//line sql.y:2311 { yyVAL.columnCharset = ColumnCharset{Name: string(yyDollar[2].str)} } case 378: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2310 +//line sql.y:2315 { // ASCII: Shorthand for CHARACTER SET latin1. yyVAL.columnCharset = ColumnCharset{Name: "latin1", Binary: yyDollar[2].booleanUnion()} } case 379: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2315 +//line sql.y:2320 { // UNICODE: Shorthand for CHARACTER SET ucs2. yyVAL.columnCharset = ColumnCharset{Name: "ucs2", Binary: yyDollar[2].booleanUnion()} } case 380: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2320 +//line sql.y:2325 { // BINARY: Shorthand for default CHARACTER SET but with binary collation yyVAL.columnCharset = ColumnCharset{Name: "", Binary: true} } case 381: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2325 +//line sql.y:2330 { // BINARY ASCII: Shorthand for CHARACTER SET latin1 with binary collation yyVAL.columnCharset = ColumnCharset{Name: "latin1", Binary: true} } case 382: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2330 +//line sql.y:2335 { // BINARY UNICODE: Shorthand for CHARACTER SET ucs2 with binary collation yyVAL.columnCharset = ColumnCharset{Name: "ucs2", Binary: true} @@ -12760,7 +12788,7 @@ yydefault: case 383: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2336 +//line sql.y:2341 { yyLOCAL = false } @@ -12768,33 +12796,33 @@ yydefault: case 384: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2340 +//line sql.y:2345 { yyLOCAL = true } yyVAL.union = yyLOCAL case 385: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2345 +//line sql.y:2350 { yyVAL.str = "" } case 386: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2349 +//line sql.y:2354 { yyVAL.str = string(yyDollar[2].identifierCI.String()) } case 387: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2353 +//line sql.y:2358 { yyVAL.str = encodeSQLString(yyDollar[2].str) } case 388: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexDefinition -//line sql.y:2359 +//line sql.y:2364 { yyLOCAL = &IndexDefinition{Info: yyDollar[1].indexInfoUnion(), Columns: yyDollar[3].indexColumnsUnion(), Options: yyDollar[5].indexOptionsUnion()} } @@ -12802,7 +12830,7 @@ yydefault: case 389: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:2364 +//line sql.y:2369 { yyLOCAL = nil } @@ -12810,7 +12838,7 @@ yydefault: case 390: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:2368 +//line sql.y:2373 { yyLOCAL = yyDollar[1].indexOptionsUnion() } @@ -12818,14 +12846,14 @@ yydefault: case 391: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:2374 +//line sql.y:2379 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } yyVAL.union = yyLOCAL case 392: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2378 +//line sql.y:2383 { yySLICE := (*[]*IndexOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].indexOptionUnion()) @@ -12833,7 +12861,7 @@ yydefault: case 393: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2384 +//line sql.y:2389 { yyLOCAL = yyDollar[1].indexOptionUnion() } @@ -12841,7 +12869,7 @@ yydefault: case 394: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2388 +//line sql.y:2393 { // should not be string yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} @@ -12850,7 +12878,7 @@ yydefault: case 395: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2393 +//line sql.y:2398 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[2].str)} } @@ -12858,7 +12886,7 @@ yydefault: case 396: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2397 +//line sql.y:2402 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str)} } @@ -12866,7 +12894,7 @@ yydefault: case 397: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2401 +//line sql.y:2406 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str)} } @@ -12874,7 +12902,7 @@ yydefault: case 398: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2405 +//line sql.y:2410 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str) + " " + string(yyDollar[2].str), String: yyDollar[3].identifierCI.String()} } @@ -12882,7 +12910,7 @@ yydefault: case 399: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2409 +//line sql.y:2414 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } @@ -12890,27 +12918,27 @@ yydefault: case 400: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2413 +//line sql.y:2418 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 401: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2419 +//line sql.y:2424 { yyVAL.str = "" } case 402: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2423 +//line sql.y:2428 { yyVAL.str = string(yyDollar[1].str) } case 403: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2429 +//line sql.y:2434 { yyLOCAL = &IndexInfo{Type: IndexTypePrimary, ConstraintName: NewIdentifierCI(yyDollar[1].str), Name: NewIdentifierCI("PRIMARY")} } @@ -12918,7 +12946,7 @@ yydefault: case 404: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2433 +//line sql.y:2438 { yyLOCAL = &IndexInfo{Type: IndexTypeSpatial, Name: NewIdentifierCI(yyDollar[3].str)} } @@ -12926,7 +12954,7 @@ yydefault: case 405: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2437 +//line sql.y:2442 { yyLOCAL = &IndexInfo{Type: IndexTypeFullText, Name: NewIdentifierCI(yyDollar[3].str)} } @@ -12934,7 +12962,7 @@ yydefault: case 406: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2441 +//line sql.y:2446 { yyLOCAL = &IndexInfo{Type: IndexTypeUnique, ConstraintName: NewIdentifierCI(yyDollar[1].str), Name: NewIdentifierCI(yyDollar[4].str)} } @@ -12942,100 +12970,100 @@ yydefault: case 407: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2445 +//line sql.y:2450 { yyLOCAL = &IndexInfo{Type: IndexTypeDefault, Name: NewIdentifierCI(yyDollar[2].str)} } yyVAL.union = yyLOCAL case 408: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2450 +//line sql.y:2455 { yyVAL.str = "" } case 409: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2454 +//line sql.y:2459 { yyVAL.str = yyDollar[2].str } case 410: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2460 +//line sql.y:2465 { yyVAL.str = string(yyDollar[1].str) } case 411: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2464 +//line sql.y:2469 { yyVAL.str = string(yyDollar[1].str) } case 412: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2468 +//line sql.y:2473 { yyVAL.str = string(yyDollar[1].str) } case 413: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2474 +//line sql.y:2479 { yyVAL.str = string(yyDollar[1].str) } case 414: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2478 +//line sql.y:2483 { yyVAL.str = string(yyDollar[1].str) } case 415: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2483 +//line sql.y:2488 { yyVAL.str = "" } case 416: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2487 +//line sql.y:2492 { yyVAL.str = yyDollar[1].str } case 417: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2493 +//line sql.y:2498 { yyVAL.str = string(yyDollar[1].str) } case 418: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2497 +//line sql.y:2502 { yyVAL.str = string(yyDollar[1].str) } case 419: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2502 +//line sql.y:2507 { yyVAL.str = "" } case 420: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2506 +//line sql.y:2511 { yyVAL.str = string(yyDollar[1].identifierCI.String()) } case 421: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexColumn -//line sql.y:2512 +//line sql.y:2517 { yyLOCAL = []*IndexColumn{yyDollar[1].indexColumnUnion()} } yyVAL.union = yyLOCAL case 422: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2516 +//line sql.y:2521 { yySLICE := (*[]*IndexColumn)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].indexColumnUnion()) @@ -13043,7 +13071,7 @@ yydefault: case 423: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexColumn -//line sql.y:2522 +//line sql.y:2527 { yyLOCAL = &IndexColumn{Column: yyDollar[1].identifierCI, Length: yyDollar[2].intPtrUnion(), Direction: yyDollar[3].orderDirectionUnion()} } @@ -13051,7 +13079,7 @@ yydefault: case 424: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *IndexColumn -//line sql.y:2526 +//line sql.y:2531 { yyLOCAL = &IndexColumn{Expression: yyDollar[2].exprUnion(), Direction: yyDollar[4].orderDirectionUnion()} } @@ -13059,7 +13087,7 @@ yydefault: case 425: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2532 +//line sql.y:2537 { yyLOCAL = &ConstraintDefinition{Name: yyDollar[2].identifierCI, Details: yyDollar[3].constraintInfoUnion()} } @@ -13067,7 +13095,7 @@ yydefault: case 426: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2536 +//line sql.y:2541 { yyLOCAL = &ConstraintDefinition{Details: yyDollar[1].constraintInfoUnion()} } @@ -13075,7 +13103,7 @@ yydefault: case 427: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2542 +//line sql.y:2547 { yyLOCAL = &ConstraintDefinition{Name: yyDollar[2].identifierCI, Details: yyDollar[3].constraintInfoUnion()} } @@ -13083,7 +13111,7 @@ yydefault: case 428: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2546 +//line sql.y:2551 { yyLOCAL = &ConstraintDefinition{Details: yyDollar[1].constraintInfoUnion()} } @@ -13091,7 +13119,7 @@ yydefault: case 429: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL ConstraintInfo -//line sql.y:2552 +//line sql.y:2557 { yyLOCAL = &ForeignKeyDefinition{IndexName: NewIdentifierCI(yyDollar[3].str), Source: yyDollar[5].columnsUnion(), ReferenceDefinition: yyDollar[7].referenceDefinitionUnion()} } @@ -13099,7 +13127,7 @@ yydefault: case 430: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2558 +//line sql.y:2563 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion()} } @@ -13107,7 +13135,7 @@ yydefault: case 431: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2562 +//line sql.y:2567 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnDelete: yyDollar[7].referenceActionUnion()} } @@ -13115,7 +13143,7 @@ yydefault: case 432: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2566 +//line sql.y:2571 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnUpdate: yyDollar[7].referenceActionUnion()} } @@ -13123,7 +13151,7 @@ yydefault: case 433: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2570 +//line sql.y:2575 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnDelete: yyDollar[7].referenceActionUnion(), OnUpdate: yyDollar[8].referenceActionUnion()} } @@ -13131,7 +13159,7 @@ yydefault: case 434: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2574 +//line sql.y:2579 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnUpdate: yyDollar[7].referenceActionUnion(), OnDelete: yyDollar[8].referenceActionUnion()} } @@ -13139,7 +13167,7 @@ yydefault: case 435: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2579 +//line sql.y:2584 { yyLOCAL = nil } @@ -13147,7 +13175,7 @@ yydefault: case 436: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2583 +//line sql.y:2588 { yyLOCAL = yyDollar[1].referenceDefinitionUnion() } @@ -13155,7 +13183,7 @@ yydefault: case 437: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL ConstraintInfo -//line sql.y:2589 +//line sql.y:2594 { yyLOCAL = &CheckConstraintDefinition{Expr: yyDollar[3].exprUnion(), Enforced: yyDollar[5].booleanUnion()} } @@ -13163,7 +13191,7 @@ yydefault: case 438: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2595 +//line sql.y:2600 { yyLOCAL = yyDollar[2].matchActionUnion() } @@ -13171,7 +13199,7 @@ yydefault: case 439: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2601 +//line sql.y:2606 { yyLOCAL = Full } @@ -13179,7 +13207,7 @@ yydefault: case 440: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2605 +//line sql.y:2610 { yyLOCAL = Partial } @@ -13187,7 +13215,7 @@ yydefault: case 441: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2609 +//line sql.y:2614 { yyLOCAL = Simple } @@ -13195,7 +13223,7 @@ yydefault: case 442: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2614 +//line sql.y:2619 { yyLOCAL = DefaultMatch } @@ -13203,7 +13231,7 @@ yydefault: case 443: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2618 +//line sql.y:2623 { yyLOCAL = yyDollar[1].matchActionUnion() } @@ -13211,7 +13239,7 @@ yydefault: case 444: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2624 +//line sql.y:2629 { yyLOCAL = yyDollar[3].referenceActionUnion() } @@ -13219,7 +13247,7 @@ yydefault: case 445: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2630 +//line sql.y:2635 { yyLOCAL = yyDollar[3].referenceActionUnion() } @@ -13227,7 +13255,7 @@ yydefault: case 446: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2636 +//line sql.y:2641 { yyLOCAL = Restrict } @@ -13235,7 +13263,7 @@ yydefault: case 447: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2640 +//line sql.y:2645 { yyLOCAL = Cascade } @@ -13243,7 +13271,7 @@ yydefault: case 448: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2644 +//line sql.y:2649 { yyLOCAL = NoAction } @@ -13251,7 +13279,7 @@ yydefault: case 449: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2648 +//line sql.y:2653 { yyLOCAL = SetDefault } @@ -13259,33 +13287,33 @@ yydefault: case 450: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:2652 +//line sql.y:2657 { yyLOCAL = SetNull } yyVAL.union = yyLOCAL case 451: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2657 +//line sql.y:2662 { yyVAL.str = "" } case 452: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2661 +//line sql.y:2666 { yyVAL.str = string(yyDollar[1].str) } case 453: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2665 +//line sql.y:2670 { yyVAL.str = string(yyDollar[1].str) } case 454: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2671 +//line sql.y:2676 { yyLOCAL = true } @@ -13293,7 +13321,7 @@ yydefault: case 455: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:2675 +//line sql.y:2680 { yyLOCAL = false } @@ -13301,7 +13329,7 @@ yydefault: case 456: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2680 +//line sql.y:2685 { yyLOCAL = true } @@ -13309,7 +13337,7 @@ yydefault: case 457: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2684 +//line sql.y:2689 { yyLOCAL = yyDollar[1].booleanUnion() } @@ -13317,7 +13345,7 @@ yydefault: case 458: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL TableOptions -//line sql.y:2689 +//line sql.y:2694 { yyLOCAL = nil } @@ -13325,7 +13353,7 @@ yydefault: case 459: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableOptions -//line sql.y:2693 +//line sql.y:2698 { yyLOCAL = yyDollar[1].tableOptionsUnion() } @@ -13333,21 +13361,21 @@ yydefault: case 460: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableOptions -//line sql.y:2699 +//line sql.y:2704 { yyLOCAL = TableOptions{yyDollar[1].tableOptionUnion()} } yyVAL.union = yyLOCAL case 461: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2703 +//line sql.y:2708 { yySLICE := (*TableOptions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableOptionUnion()) } case 462: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2707 +//line sql.y:2712 { yySLICE := (*TableOptions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].tableOptionUnion()) @@ -13355,14 +13383,14 @@ yydefault: case 463: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableOptions -//line sql.y:2713 +//line sql.y:2718 { yyLOCAL = TableOptions{yyDollar[1].tableOptionUnion()} } yyVAL.union = yyLOCAL case 464: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2717 +//line sql.y:2722 { yySLICE := (*TableOptions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].tableOptionUnion()) @@ -13370,7 +13398,7 @@ yydefault: case 465: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2723 +//line sql.y:2728 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13378,7 +13406,7 @@ yydefault: case 466: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2727 +//line sql.y:2732 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13386,7 +13414,7 @@ yydefault: case 467: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2731 +//line sql.y:2736 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13394,7 +13422,7 @@ yydefault: case 468: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2735 +//line sql.y:2740 { yyLOCAL = &TableOption{Name: (string(yyDollar[2].str)), String: yyDollar[4].str, CaseSensitive: true} } @@ -13402,7 +13430,7 @@ yydefault: case 469: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2739 +//line sql.y:2744 { yyLOCAL = &TableOption{Name: string(yyDollar[2].str), String: yyDollar[4].str, CaseSensitive: true} } @@ -13410,7 +13438,7 @@ yydefault: case 470: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2743 +//line sql.y:2748 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13418,7 +13446,7 @@ yydefault: case 471: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2747 +//line sql.y:2752 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } @@ -13426,7 +13454,7 @@ yydefault: case 472: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2751 +//line sql.y:2756 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } @@ -13434,7 +13462,7 @@ yydefault: case 473: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2755 +//line sql.y:2760 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } @@ -13442,7 +13470,7 @@ yydefault: case 474: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2759 +//line sql.y:2764 { yyLOCAL = &TableOption{Name: (string(yyDollar[1].str) + " " + string(yyDollar[2].str)), Value: NewStrLiteral(yyDollar[4].str)} } @@ -13450,7 +13478,7 @@ yydefault: case 475: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2763 +//line sql.y:2768 { yyLOCAL = &TableOption{Name: (string(yyDollar[1].str) + " " + string(yyDollar[2].str)), Value: NewStrLiteral(yyDollar[4].str)} } @@ -13458,7 +13486,7 @@ yydefault: case 476: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2767 +//line sql.y:2772 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13466,7 +13494,7 @@ yydefault: case 477: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2771 +//line sql.y:2776 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } @@ -13474,7 +13502,7 @@ yydefault: case 478: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2775 +//line sql.y:2780 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: yyDollar[3].identifierCS.String(), CaseSensitive: true} } @@ -13482,7 +13510,7 @@ yydefault: case 479: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2779 +//line sql.y:2784 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } @@ -13490,7 +13518,7 @@ yydefault: case 480: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2783 +//line sql.y:2788 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } @@ -13498,7 +13526,7 @@ yydefault: case 481: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2787 +//line sql.y:2792 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13506,7 +13534,7 @@ yydefault: case 482: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2791 +//line sql.y:2796 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13514,7 +13542,7 @@ yydefault: case 483: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2795 +//line sql.y:2800 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13522,7 +13550,7 @@ yydefault: case 484: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2799 +//line sql.y:2804 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13530,7 +13558,7 @@ yydefault: case 485: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2803 +//line sql.y:2808 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } @@ -13538,7 +13566,7 @@ yydefault: case 486: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2807 +//line sql.y:2812 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } @@ -13546,7 +13574,7 @@ yydefault: case 487: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2811 +//line sql.y:2816 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } @@ -13554,7 +13582,7 @@ yydefault: case 488: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2815 +//line sql.y:2820 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } @@ -13562,7 +13590,7 @@ yydefault: case 489: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2819 +//line sql.y:2824 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13570,7 +13598,7 @@ yydefault: case 490: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2823 +//line sql.y:2828 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } @@ -13578,7 +13606,7 @@ yydefault: case 491: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2827 +//line sql.y:2832 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13586,7 +13614,7 @@ yydefault: case 492: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2831 +//line sql.y:2836 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } @@ -13594,7 +13622,7 @@ yydefault: case 493: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2835 +//line sql.y:2840 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } @@ -13602,7 +13630,7 @@ yydefault: case 494: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2839 +//line sql.y:2844 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: (yyDollar[3].identifierCI.String() + yyDollar[4].str), CaseSensitive: true} } @@ -13610,63 +13638,63 @@ yydefault: case 495: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *TableOption -//line sql.y:2843 +//line sql.y:2848 { yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Tables: yyDollar[4].tableNamesUnion()} } yyVAL.union = yyLOCAL case 496: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2848 +//line sql.y:2853 { yyVAL.str = "" } case 497: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2852 +//line sql.y:2857 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 498: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2856 +//line sql.y:2861 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 508: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2875 +//line sql.y:2880 { yyVAL.str = String(TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}) } case 509: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2879 +//line sql.y:2884 { yyVAL.str = yyDollar[1].identifierCI.String() } case 510: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2883 +//line sql.y:2888 { yyVAL.str = encodeSQLString(yyDollar[1].str) } case 511: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2887 +//line sql.y:2892 { yyVAL.str = string(yyDollar[1].str) } case 512: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2892 +//line sql.y:2897 { yyVAL.str = "" } case 514: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2898 +//line sql.y:2903 { yyLOCAL = false } @@ -13674,7 +13702,7 @@ yydefault: case 515: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2902 +//line sql.y:2907 { yyLOCAL = true } @@ -13682,7 +13710,7 @@ yydefault: case 516: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ColName -//line sql.y:2907 +//line sql.y:2912 { yyLOCAL = nil } @@ -13690,27 +13718,27 @@ yydefault: case 517: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColName -//line sql.y:2911 +//line sql.y:2916 { yyLOCAL = yyDollar[2].colNameUnion() } yyVAL.union = yyLOCAL case 518: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2916 +//line sql.y:2921 { yyVAL.str = "" } case 519: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2920 +//line sql.y:2925 { yyVAL.str = string(yyDollar[2].str) } case 520: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Literal -//line sql.y:2925 +//line sql.y:2930 { yyLOCAL = nil } @@ -13718,7 +13746,7 @@ yydefault: case 521: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Literal -//line sql.y:2929 +//line sql.y:2934 { yyLOCAL = NewIntLiteral(yyDollar[2].str) } @@ -13726,7 +13754,7 @@ yydefault: case 522: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Literal -//line sql.y:2933 +//line sql.y:2938 { yyLOCAL = NewDecimalLiteral(yyDollar[2].str) } @@ -13734,7 +13762,7 @@ yydefault: case 523: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:2938 +//line sql.y:2943 { yyLOCAL = nil } @@ -13742,14 +13770,14 @@ yydefault: case 524: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:2942 +//line sql.y:2947 { yyLOCAL = yyDollar[1].alterOptionsUnion() } yyVAL.union = yyLOCAL case 525: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2946 +//line sql.y:2951 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, &OrderByOption{Cols: yyDollar[5].columnsUnion()}) @@ -13757,14 +13785,14 @@ yydefault: case 526: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:2950 +//line sql.y:2955 { yyLOCAL = yyDollar[1].alterOptionsUnion() } yyVAL.union = yyLOCAL case 527: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2954 +//line sql.y:2959 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionsUnion()...) @@ -13772,7 +13800,7 @@ yydefault: case 528: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:2958 +//line sql.y:2963 { yyLOCAL = append(append(yyDollar[1].alterOptionsUnion(), yyDollar[3].alterOptionsUnion()...), &OrderByOption{Cols: yyDollar[7].columnsUnion()}) } @@ -13780,21 +13808,21 @@ yydefault: case 529: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:2964 +//line sql.y:2969 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL case 530: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2968 +//line sql.y:2973 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) } case 531: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2972 +//line sql.y:2977 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) @@ -13802,7 +13830,7 @@ yydefault: case 532: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2978 +//line sql.y:2983 { yyLOCAL = yyDollar[1].tableOptionsUnion() } @@ -13810,7 +13838,7 @@ yydefault: case 533: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2982 +//line sql.y:2987 { yyLOCAL = &AddConstraintDefinition{ConstraintDefinition: yyDollar[2].constraintDefinitionUnion()} } @@ -13818,7 +13846,7 @@ yydefault: case 534: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2986 +//line sql.y:2991 { yyLOCAL = &AddConstraintDefinition{ConstraintDefinition: yyDollar[2].constraintDefinitionUnion()} } @@ -13826,7 +13854,7 @@ yydefault: case 535: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2990 +//line sql.y:2995 { yyLOCAL = &AddIndexDefinition{IndexDefinition: yyDollar[2].indexDefinitionUnion()} } @@ -13834,7 +13862,7 @@ yydefault: case 536: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2994 +//line sql.y:2999 { yyLOCAL = &AddColumns{Columns: yyDollar[4].columnDefinitionsUnion()} } @@ -13842,7 +13870,7 @@ yydefault: case 537: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2998 +//line sql.y:3003 { yyLOCAL = &AddColumns{Columns: []*ColumnDefinition{yyDollar[3].columnDefinitionUnion()}, First: yyDollar[4].booleanUnion(), After: yyDollar[5].colNameUnion()} } @@ -13850,7 +13878,7 @@ yydefault: case 538: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3002 +//line sql.y:3007 { yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: true} } @@ -13858,7 +13886,7 @@ yydefault: case 539: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3006 +//line sql.y:3011 { yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: false, DefaultVal: yyDollar[6].exprUnion(), DefaultLiteral: true} } @@ -13866,7 +13894,7 @@ yydefault: case 540: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3010 +//line sql.y:3015 { yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: false, DefaultVal: yyDollar[7].exprUnion()} } @@ -13874,7 +13902,7 @@ yydefault: case 541: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3014 +//line sql.y:3019 { yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), Invisible: ptr.Of(false)} } @@ -13882,7 +13910,7 @@ yydefault: case 542: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3018 +//line sql.y:3023 { yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), Invisible: ptr.Of(true)} } @@ -13890,7 +13918,7 @@ yydefault: case 543: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3022 +//line sql.y:3027 { yyLOCAL = &AlterCheck{Name: yyDollar[3].identifierCI, Enforced: yyDollar[4].booleanUnion()} } @@ -13898,7 +13926,7 @@ yydefault: case 544: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3026 +//line sql.y:3031 { yyLOCAL = &AlterIndex{Name: yyDollar[3].identifierCI, Invisible: false} } @@ -13906,7 +13934,7 @@ yydefault: case 545: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3030 +//line sql.y:3035 { yyLOCAL = &AlterIndex{Name: yyDollar[3].identifierCI, Invisible: true} } @@ -13914,7 +13942,7 @@ yydefault: case 546: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3034 +//line sql.y:3039 { yyLOCAL = &ChangeColumn{OldColumn: yyDollar[3].colNameUnion(), NewColDefinition: yyDollar[4].columnDefinitionUnion(), First: yyDollar[5].booleanUnion(), After: yyDollar[6].colNameUnion()} } @@ -13922,7 +13950,7 @@ yydefault: case 547: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3038 +//line sql.y:3043 { yyLOCAL = &ModifyColumn{NewColDefinition: yyDollar[3].columnDefinitionUnion(), First: yyDollar[4].booleanUnion(), After: yyDollar[5].colNameUnion()} } @@ -13930,7 +13958,7 @@ yydefault: case 548: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3042 +//line sql.y:3047 { yyLOCAL = &RenameColumn{OldName: yyDollar[3].colNameUnion(), NewName: yyDollar[5].colNameUnion()} } @@ -13938,7 +13966,7 @@ yydefault: case 549: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3046 +//line sql.y:3051 { yyLOCAL = &AlterCharset{CharacterSet: yyDollar[4].str, Collate: yyDollar[5].str} } @@ -13946,7 +13974,7 @@ yydefault: case 550: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3050 +//line sql.y:3055 { yyLOCAL = &KeyState{Enable: false} } @@ -13954,7 +13982,7 @@ yydefault: case 551: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3054 +//line sql.y:3059 { yyLOCAL = &KeyState{Enable: true} } @@ -13962,7 +13990,7 @@ yydefault: case 552: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3058 +//line sql.y:3063 { yyLOCAL = &TablespaceOperation{Import: false} } @@ -13970,7 +13998,7 @@ yydefault: case 553: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3062 +//line sql.y:3067 { yyLOCAL = &TablespaceOperation{Import: true} } @@ -13978,7 +14006,7 @@ yydefault: case 554: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3066 +//line sql.y:3071 { yyLOCAL = &DropColumn{Name: yyDollar[3].colNameUnion()} } @@ -13986,7 +14014,7 @@ yydefault: case 555: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3070 +//line sql.y:3075 { yyLOCAL = &DropKey{Type: NormalKeyType, Name: yyDollar[3].identifierCI} } @@ -13994,7 +14022,7 @@ yydefault: case 556: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3074 +//line sql.y:3079 { yyLOCAL = &DropKey{Type: PrimaryKeyType} } @@ -14002,7 +14030,7 @@ yydefault: case 557: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3078 +//line sql.y:3083 { yyLOCAL = &DropKey{Type: ForeignKeyType, Name: yyDollar[4].identifierCI} } @@ -14010,7 +14038,7 @@ yydefault: case 558: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3082 +//line sql.y:3087 { yyLOCAL = &DropKey{Type: CheckKeyType, Name: yyDollar[3].identifierCI} } @@ -14018,7 +14046,7 @@ yydefault: case 559: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3086 +//line sql.y:3091 { yyLOCAL = &DropKey{Type: CheckKeyType, Name: yyDollar[3].identifierCI} } @@ -14026,7 +14054,7 @@ yydefault: case 560: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3090 +//line sql.y:3095 { yyLOCAL = &Force{} } @@ -14034,7 +14062,7 @@ yydefault: case 561: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3094 +//line sql.y:3099 { yyLOCAL = &RenameTableName{Table: yyDollar[3].tableName} } @@ -14042,7 +14070,7 @@ yydefault: case 562: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3098 +//line sql.y:3103 { yyLOCAL = &RenameIndex{OldName: yyDollar[3].identifierCI, NewName: yyDollar[5].identifierCI} } @@ -14050,14 +14078,14 @@ yydefault: case 563: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:3104 +//line sql.y:3109 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL case 564: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3108 +//line sql.y:3113 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) @@ -14065,7 +14093,7 @@ yydefault: case 565: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3114 +//line sql.y:3119 { yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) } @@ -14073,7 +14101,7 @@ yydefault: case 566: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3118 +//line sql.y:3123 { yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) } @@ -14081,7 +14109,7 @@ yydefault: case 567: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3122 +//line sql.y:3127 { yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) } @@ -14089,7 +14117,7 @@ yydefault: case 568: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3126 +//line sql.y:3131 { yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) } @@ -14097,7 +14125,7 @@ yydefault: case 569: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3130 +//line sql.y:3135 { yyLOCAL = &LockOption{Type: DefaultType} } @@ -14105,7 +14133,7 @@ yydefault: case 570: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3134 +//line sql.y:3139 { yyLOCAL = &LockOption{Type: NoneType} } @@ -14113,7 +14141,7 @@ yydefault: case 571: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3138 +//line sql.y:3143 { yyLOCAL = &LockOption{Type: SharedType} } @@ -14121,7 +14149,7 @@ yydefault: case 572: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3142 +//line sql.y:3147 { yyLOCAL = &LockOption{Type: ExclusiveType} } @@ -14129,7 +14157,7 @@ yydefault: case 573: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3146 +//line sql.y:3151 { yyLOCAL = &Validation{With: true} } @@ -14137,7 +14165,7 @@ yydefault: case 574: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption -//line sql.y:3150 +//line sql.y:3155 { yyLOCAL = &Validation{With: false} } @@ -14145,7 +14173,7 @@ yydefault: case 575: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3156 +//line sql.y:3161 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() @@ -14156,7 +14184,7 @@ yydefault: case 576: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:3163 +//line sql.y:3168 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() @@ -14167,7 +14195,7 @@ yydefault: case 577: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:3170 +//line sql.y:3175 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() @@ -14178,7 +14206,7 @@ yydefault: case 578: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:3177 +//line sql.y:3182 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().PartitionSpec = yyDollar[2].partSpecUnion() @@ -14188,7 +14216,7 @@ yydefault: case 579: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL Statement -//line sql.y:3183 +//line sql.y:3188 { yyLOCAL = &AlterView{ViewName: yyDollar[7].tableName, Comments: Comments(yyDollar[2].strs).Parsed(), Algorithm: yyDollar[3].str, Definer: yyDollar[4].definerUnion(), Security: yyDollar[5].str, Columns: yyDollar[8].columnsUnion(), Select: yyDollar[10].selStmtUnion(), CheckOption: yyDollar[11].str} } @@ -14196,7 +14224,7 @@ yydefault: case 580: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3193 +//line sql.y:3198 { yyDollar[1].alterDatabaseUnion().FullyParsed = true yyDollar[1].alterDatabaseUnion().DBName = yyDollar[2].identifierCS @@ -14207,7 +14235,7 @@ yydefault: case 581: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3200 +//line sql.y:3205 { yyDollar[1].alterDatabaseUnion().FullyParsed = true yyDollar[1].alterDatabaseUnion().DBName = yyDollar[2].identifierCS @@ -14218,7 +14246,7 @@ yydefault: case 582: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:3207 +//line sql.y:3212 { yyLOCAL = &AlterVschema{ Action: CreateVindexDDLAction, @@ -14234,7 +14262,7 @@ yydefault: case 583: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3219 +//line sql.y:3224 { yyLOCAL = &AlterVschema{ Action: DropVindexDDLAction, @@ -14248,7 +14276,7 @@ yydefault: case 584: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3229 +//line sql.y:3234 { yyLOCAL = &AlterVschema{Action: AddVschemaTableDDLAction, Table: yyDollar[6].tableName} } @@ -14256,7 +14284,7 @@ yydefault: case 585: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3233 +//line sql.y:3238 { yyLOCAL = &AlterVschema{Action: DropVschemaTableDDLAction, Table: yyDollar[6].tableName} } @@ -14264,7 +14292,7 @@ yydefault: case 586: yyDollar = yyS[yypt-13 : yypt+1] var yyLOCAL Statement -//line sql.y:3237 +//line sql.y:3242 { yyLOCAL = &AlterVschema{ Action: AddColVindexDDLAction, @@ -14281,7 +14309,7 @@ yydefault: case 587: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:3250 +//line sql.y:3255 { yyLOCAL = &AlterVschema{ Action: DropColVindexDDLAction, @@ -14295,7 +14323,7 @@ yydefault: case 588: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3260 +//line sql.y:3265 { yyLOCAL = &AlterVschema{Action: AddSequenceDDLAction, Table: yyDollar[6].tableName} } @@ -14303,7 +14331,7 @@ yydefault: case 589: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3264 +//line sql.y:3269 { yyLOCAL = &AlterVschema{Action: DropSequenceDDLAction, Table: yyDollar[6].tableName} } @@ -14311,7 +14339,7 @@ yydefault: case 590: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Statement -//line sql.y:3268 +//line sql.y:3273 { yyLOCAL = &AlterVschema{ Action: AddAutoIncDDLAction, @@ -14326,7 +14354,7 @@ yydefault: case 591: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3279 +//line sql.y:3284 { yyLOCAL = &AlterVschema{ Action: DropAutoIncDDLAction, @@ -14337,7 +14365,7 @@ yydefault: case 592: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3286 +//line sql.y:3291 { yyLOCAL = &AlterMigration{ Type: RetryMigrationType, @@ -14348,7 +14376,7 @@ yydefault: case 593: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3293 +//line sql.y:3298 { yyLOCAL = &AlterMigration{ Type: CleanupMigrationType, @@ -14359,7 +14387,7 @@ yydefault: case 594: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3300 +//line sql.y:3305 { yyLOCAL = &AlterMigration{ Type: LaunchMigrationType, @@ -14370,7 +14398,7 @@ yydefault: case 595: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3307 +//line sql.y:3312 { yyLOCAL = &AlterMigration{ Type: LaunchMigrationType, @@ -14382,7 +14410,7 @@ yydefault: case 596: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3315 +//line sql.y:3320 { yyLOCAL = &AlterMigration{ Type: LaunchAllMigrationType, @@ -14392,7 +14420,7 @@ yydefault: case 597: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3321 +//line sql.y:3326 { yyLOCAL = &AlterMigration{ Type: CompleteMigrationType, @@ -14403,7 +14431,7 @@ yydefault: case 598: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3328 +//line sql.y:3333 { yyLOCAL = &AlterMigration{ Type: CompleteAllMigrationType, @@ -14413,7 +14441,7 @@ yydefault: case 599: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3334 +//line sql.y:3339 { yyLOCAL = &AlterMigration{ Type: CancelMigrationType, @@ -14424,7 +14452,7 @@ yydefault: case 600: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3341 +//line sql.y:3346 { yyLOCAL = &AlterMigration{ Type: CancelAllMigrationType, @@ -14434,7 +14462,7 @@ yydefault: case 601: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3347 +//line sql.y:3352 { yyLOCAL = &AlterMigration{ Type: ThrottleMigrationType, @@ -14447,7 +14475,7 @@ yydefault: case 602: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3356 +//line sql.y:3361 { yyLOCAL = &AlterMigration{ Type: ThrottleAllMigrationType, @@ -14459,7 +14487,7 @@ yydefault: case 603: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3364 +//line sql.y:3369 { yyLOCAL = &AlterMigration{ Type: UnthrottleMigrationType, @@ -14470,7 +14498,7 @@ yydefault: case 604: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3371 +//line sql.y:3376 { yyLOCAL = &AlterMigration{ Type: UnthrottleAllMigrationType, @@ -14480,7 +14508,7 @@ yydefault: case 605: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3377 +//line sql.y:3382 { yyLOCAL = &AlterMigration{ Type: ForceCutOverMigrationType, @@ -14491,7 +14519,7 @@ yydefault: case 606: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3384 +//line sql.y:3389 { yyLOCAL = &AlterMigration{ Type: ForceCutOverAllMigrationType, @@ -14501,7 +14529,7 @@ yydefault: case 607: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3391 +//line sql.y:3396 { yyLOCAL = nil } @@ -14509,7 +14537,7 @@ yydefault: case 608: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3395 +//line sql.y:3400 { yyDollar[3].partitionOptionUnion().Partitions = yyDollar[4].integerUnion() yyDollar[3].partitionOptionUnion().SubPartition = yyDollar[5].subPartitionUnion() @@ -14520,7 +14548,7 @@ yydefault: case 609: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3404 +//line sql.y:3409 { yyLOCAL = &PartitionOption{ IsLinear: yyDollar[1].booleanUnion(), @@ -14532,7 +14560,7 @@ yydefault: case 610: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3412 +//line sql.y:3417 { yyLOCAL = &PartitionOption{ IsLinear: yyDollar[1].booleanUnion(), @@ -14545,7 +14573,7 @@ yydefault: case 611: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3421 +//line sql.y:3426 { yyLOCAL = &PartitionOption{ Type: yyDollar[1].partitionByTypeUnion(), @@ -14556,7 +14584,7 @@ yydefault: case 612: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3428 +//line sql.y:3433 { yyLOCAL = &PartitionOption{ Type: yyDollar[1].partitionByTypeUnion(), @@ -14567,7 +14595,7 @@ yydefault: case 613: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3436 +//line sql.y:3441 { yyLOCAL = nil } @@ -14575,7 +14603,7 @@ yydefault: case 614: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3440 +//line sql.y:3445 { yyLOCAL = &SubPartition{ IsLinear: yyDollar[3].booleanUnion(), @@ -14588,7 +14616,7 @@ yydefault: case 615: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3449 +//line sql.y:3454 { yyLOCAL = &SubPartition{ IsLinear: yyDollar[3].booleanUnion(), @@ -14602,7 +14630,7 @@ yydefault: case 616: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:3460 +//line sql.y:3465 { yyLOCAL = nil } @@ -14610,7 +14638,7 @@ yydefault: case 617: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:3464 +//line sql.y:3469 { yyLOCAL = yyDollar[2].partDefsUnion() } @@ -14618,7 +14646,7 @@ yydefault: case 618: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3469 +//line sql.y:3474 { yyLOCAL = false } @@ -14626,7 +14654,7 @@ yydefault: case 619: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3473 +//line sql.y:3478 { yyLOCAL = true } @@ -14634,7 +14662,7 @@ yydefault: case 620: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:3478 +//line sql.y:3483 { yyLOCAL = 0 } @@ -14642,7 +14670,7 @@ yydefault: case 621: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:3482 +//line sql.y:3487 { yyLOCAL = convertStringToInt(yyDollar[3].str) } @@ -14650,7 +14678,7 @@ yydefault: case 622: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3488 +//line sql.y:3493 { yyLOCAL = &JSONTableExpr{Expr: yyDollar[3].exprUnion(), Filter: yyDollar[5].exprUnion(), Columns: yyDollar[6].jtColumnListUnion(), Alias: yyDollar[8].identifierCS} } @@ -14658,7 +14686,7 @@ yydefault: case 623: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL []*JtColumnDefinition -//line sql.y:3494 +//line sql.y:3499 { yyLOCAL = yyDollar[3].jtColumnListUnion() } @@ -14666,14 +14694,14 @@ yydefault: case 624: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*JtColumnDefinition -//line sql.y:3500 +//line sql.y:3505 { yyLOCAL = []*JtColumnDefinition{yyDollar[1].jtColumnDefinitionUnion()} } yyVAL.union = yyLOCAL case 625: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3504 +//line sql.y:3509 { yySLICE := (*[]*JtColumnDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].jtColumnDefinitionUnion()) @@ -14681,7 +14709,7 @@ yydefault: case 626: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3510 +//line sql.y:3515 { yyLOCAL = &JtColumnDefinition{JtOrdinal: &JtOrdinalColDef{Name: yyDollar[1].identifierCI}} } @@ -14689,7 +14717,7 @@ yydefault: case 627: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3514 +//line sql.y:3519 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion()} @@ -14699,7 +14727,7 @@ yydefault: case 628: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3520 +//line sql.y:3525 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion()} @@ -14709,7 +14737,7 @@ yydefault: case 629: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3526 +//line sql.y:3531 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion(), ErrorOnResponse: yyDollar[7].jtOnResponseUnion()} @@ -14719,7 +14747,7 @@ yydefault: case 630: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3532 +//line sql.y:3537 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion(), ErrorOnResponse: yyDollar[8].jtOnResponseUnion()} @@ -14729,7 +14757,7 @@ yydefault: case 631: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3538 +//line sql.y:3543 { jtNestedPath := &JtNestedPathColDef{Path: yyDollar[3].exprUnion(), Columns: yyDollar[4].jtColumnListUnion()} yyLOCAL = &JtColumnDefinition{JtNestedPath: jtNestedPath} @@ -14738,7 +14766,7 @@ yydefault: case 632: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3544 +//line sql.y:3549 { yyLOCAL = false } @@ -14746,7 +14774,7 @@ yydefault: case 633: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3548 +//line sql.y:3553 { yyLOCAL = true } @@ -14754,7 +14782,7 @@ yydefault: case 634: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3552 +//line sql.y:3557 { yyLOCAL = false } @@ -14762,7 +14790,7 @@ yydefault: case 635: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3556 +//line sql.y:3561 { yyLOCAL = true } @@ -14770,7 +14798,7 @@ yydefault: case 636: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3562 +//line sql.y:3567 { yyLOCAL = yyDollar[1].jtOnResponseUnion() } @@ -14778,7 +14806,7 @@ yydefault: case 637: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3568 +//line sql.y:3573 { yyLOCAL = yyDollar[1].jtOnResponseUnion() } @@ -14786,7 +14814,7 @@ yydefault: case 638: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3574 +//line sql.y:3579 { yyLOCAL = &JtOnResponse{ResponseType: ErrorJSONType} } @@ -14794,7 +14822,7 @@ yydefault: case 639: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3578 +//line sql.y:3583 { yyLOCAL = &JtOnResponse{ResponseType: NullJSONType} } @@ -14802,7 +14830,7 @@ yydefault: case 640: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3582 +//line sql.y:3587 { yyLOCAL = &JtOnResponse{ResponseType: DefaultJSONType, Expr: yyDollar[2].exprUnion()} } @@ -14810,7 +14838,7 @@ yydefault: case 641: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL PartitionByType -//line sql.y:3588 +//line sql.y:3593 { yyLOCAL = RangeType } @@ -14818,7 +14846,7 @@ yydefault: case 642: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL PartitionByType -//line sql.y:3592 +//line sql.y:3597 { yyLOCAL = ListType } @@ -14826,7 +14854,7 @@ yydefault: case 643: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:3597 +//line sql.y:3602 { yyLOCAL = -1 } @@ -14834,7 +14862,7 @@ yydefault: case 644: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:3601 +//line sql.y:3606 { yyLOCAL = convertStringToInt(yyDollar[2].str) } @@ -14842,7 +14870,7 @@ yydefault: case 645: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:3606 +//line sql.y:3611 { yyLOCAL = -1 } @@ -14850,7 +14878,7 @@ yydefault: case 646: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:3610 +//line sql.y:3615 { yyLOCAL = convertStringToInt(yyDollar[2].str) } @@ -14858,7 +14886,7 @@ yydefault: case 647: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3616 +//line sql.y:3621 { yyLOCAL = &PartitionSpec{Action: AddAction, Definitions: []*PartitionDefinition{yyDollar[4].partDefUnion()}} } @@ -14866,7 +14894,7 @@ yydefault: case 648: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3620 +//line sql.y:3625 { yyLOCAL = &PartitionSpec{Action: DropAction, Names: yyDollar[3].partitionsUnion()} } @@ -14874,7 +14902,7 @@ yydefault: case 649: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3624 +//line sql.y:3629 { yyLOCAL = &PartitionSpec{Action: ReorganizeAction, Names: yyDollar[3].partitionsUnion(), Definitions: yyDollar[6].partDefsUnion()} } @@ -14882,7 +14910,7 @@ yydefault: case 650: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3628 +//line sql.y:3633 { yyLOCAL = &PartitionSpec{Action: DiscardAction, Names: yyDollar[3].partitionsUnion()} } @@ -14890,7 +14918,7 @@ yydefault: case 651: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3632 +//line sql.y:3637 { yyLOCAL = &PartitionSpec{Action: DiscardAction, IsAll: true} } @@ -14898,7 +14926,7 @@ yydefault: case 652: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3636 +//line sql.y:3641 { yyLOCAL = &PartitionSpec{Action: ImportAction, Names: yyDollar[3].partitionsUnion()} } @@ -14906,7 +14934,7 @@ yydefault: case 653: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3640 +//line sql.y:3645 { yyLOCAL = &PartitionSpec{Action: ImportAction, IsAll: true} } @@ -14914,7 +14942,7 @@ yydefault: case 654: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3644 +//line sql.y:3649 { yyLOCAL = &PartitionSpec{Action: TruncateAction, Names: yyDollar[3].partitionsUnion()} } @@ -14922,7 +14950,7 @@ yydefault: case 655: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3648 +//line sql.y:3653 { yyLOCAL = &PartitionSpec{Action: TruncateAction, IsAll: true} } @@ -14930,7 +14958,7 @@ yydefault: case 656: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3652 +//line sql.y:3657 { yyLOCAL = &PartitionSpec{Action: CoalesceAction, Number: NewIntLiteral(yyDollar[3].str)} } @@ -14938,7 +14966,7 @@ yydefault: case 657: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3656 +//line sql.y:3661 { yyLOCAL = &PartitionSpec{Action: ExchangeAction, Names: Partitions{yyDollar[3].identifierCI}, TableName: yyDollar[6].tableName, WithoutValidation: yyDollar[7].booleanUnion()} } @@ -14946,7 +14974,7 @@ yydefault: case 658: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3660 +//line sql.y:3665 { yyLOCAL = &PartitionSpec{Action: AnalyzeAction, Names: yyDollar[3].partitionsUnion()} } @@ -14954,7 +14982,7 @@ yydefault: case 659: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3664 +//line sql.y:3669 { yyLOCAL = &PartitionSpec{Action: AnalyzeAction, IsAll: true} } @@ -14962,7 +14990,7 @@ yydefault: case 660: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3668 +//line sql.y:3673 { yyLOCAL = &PartitionSpec{Action: CheckAction, Names: yyDollar[3].partitionsUnion()} } @@ -14970,7 +14998,7 @@ yydefault: case 661: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3672 +//line sql.y:3677 { yyLOCAL = &PartitionSpec{Action: CheckAction, IsAll: true} } @@ -14978,7 +15006,7 @@ yydefault: case 662: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3676 +//line sql.y:3681 { yyLOCAL = &PartitionSpec{Action: OptimizeAction, Names: yyDollar[3].partitionsUnion()} } @@ -14986,7 +15014,7 @@ yydefault: case 663: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3680 +//line sql.y:3685 { yyLOCAL = &PartitionSpec{Action: OptimizeAction, IsAll: true} } @@ -14994,7 +15022,7 @@ yydefault: case 664: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3684 +//line sql.y:3689 { yyLOCAL = &PartitionSpec{Action: RebuildAction, Names: yyDollar[3].partitionsUnion()} } @@ -15002,7 +15030,7 @@ yydefault: case 665: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3688 +//line sql.y:3693 { yyLOCAL = &PartitionSpec{Action: RebuildAction, IsAll: true} } @@ -15010,7 +15038,7 @@ yydefault: case 666: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3692 +//line sql.y:3697 { yyLOCAL = &PartitionSpec{Action: RepairAction, Names: yyDollar[3].partitionsUnion()} } @@ -15018,7 +15046,7 @@ yydefault: case 667: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3696 +//line sql.y:3701 { yyLOCAL = &PartitionSpec{Action: RepairAction, IsAll: true} } @@ -15026,7 +15054,7 @@ yydefault: case 668: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:3700 +//line sql.y:3705 { yyLOCAL = &PartitionSpec{Action: UpgradeAction} } @@ -15034,7 +15062,7 @@ yydefault: case 669: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3705 +//line sql.y:3710 { yyLOCAL = false } @@ -15042,7 +15070,7 @@ yydefault: case 670: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:3709 +//line sql.y:3714 { yyLOCAL = false } @@ -15050,7 +15078,7 @@ yydefault: case 671: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:3713 +//line sql.y:3718 { yyLOCAL = true } @@ -15058,28 +15086,28 @@ yydefault: case 672: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:3719 +//line sql.y:3724 { yyLOCAL = []*PartitionDefinition{yyDollar[1].partDefUnion()} } yyVAL.union = yyLOCAL case 673: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3723 +//line sql.y:3728 { yySLICE := (*[]*PartitionDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].partDefUnion()) } case 674: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3729 +//line sql.y:3734 { yyVAL.partDefUnion().Options = yyDollar[2].partitionDefinitionOptionsUnion() } case 675: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3734 +//line sql.y:3739 { yyLOCAL = &PartitionDefinitionOptions{} } @@ -15087,7 +15115,7 @@ yydefault: case 676: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3738 +//line sql.y:3743 { yyDollar[1].partitionDefinitionOptionsUnion().ValueRange = yyDollar[2].partitionValueRangeUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() @@ -15096,7 +15124,7 @@ yydefault: case 677: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3743 +//line sql.y:3748 { yyDollar[1].partitionDefinitionOptionsUnion().Comment = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() @@ -15105,7 +15133,7 @@ yydefault: case 678: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3748 +//line sql.y:3753 { yyDollar[1].partitionDefinitionOptionsUnion().Engine = yyDollar[2].partitionEngineUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() @@ -15114,7 +15142,7 @@ yydefault: case 679: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3753 +//line sql.y:3758 { yyDollar[1].partitionDefinitionOptionsUnion().DataDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() @@ -15123,7 +15151,7 @@ yydefault: case 680: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3758 +//line sql.y:3763 { yyDollar[1].partitionDefinitionOptionsUnion().IndexDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() @@ -15132,7 +15160,7 @@ yydefault: case 681: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3763 +//line sql.y:3768 { yyDollar[1].partitionDefinitionOptionsUnion().MaxRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() @@ -15141,7 +15169,7 @@ yydefault: case 682: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3768 +//line sql.y:3773 { yyDollar[1].partitionDefinitionOptionsUnion().MinRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() @@ -15150,7 +15178,7 @@ yydefault: case 683: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3773 +//line sql.y:3778 { yyDollar[1].partitionDefinitionOptionsUnion().TableSpace = yyDollar[2].str yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() @@ -15159,7 +15187,7 @@ yydefault: case 684: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:3778 +//line sql.y:3783 { yyDollar[1].partitionDefinitionOptionsUnion().SubPartitionDefinitions = yyDollar[2].subPartitionDefinitionsUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() @@ -15168,7 +15196,7 @@ yydefault: case 685: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SubPartitionDefinitions -//line sql.y:3784 +//line sql.y:3789 { yyLOCAL = yyDollar[2].subPartitionDefinitionsUnion() } @@ -15176,14 +15204,14 @@ yydefault: case 686: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SubPartitionDefinitions -//line sql.y:3790 +//line sql.y:3795 { yyLOCAL = SubPartitionDefinitions{yyDollar[1].subPartitionDefinitionUnion()} } yyVAL.union = yyLOCAL case 687: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3794 +//line sql.y:3799 { yySLICE := (*SubPartitionDefinitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].subPartitionDefinitionUnion()) @@ -15191,7 +15219,7 @@ yydefault: case 688: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SubPartitionDefinition -//line sql.y:3800 +//line sql.y:3805 { yyLOCAL = &SubPartitionDefinition{Name: yyDollar[2].identifierCI, Options: yyDollar[3].subPartitionDefinitionOptionsUnion()} } @@ -15199,7 +15227,7 @@ yydefault: case 689: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3805 +//line sql.y:3810 { yyLOCAL = &SubPartitionDefinitionOptions{} } @@ -15207,7 +15235,7 @@ yydefault: case 690: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3809 +//line sql.y:3814 { yyDollar[1].subPartitionDefinitionOptionsUnion().Comment = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() @@ -15216,7 +15244,7 @@ yydefault: case 691: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3814 +//line sql.y:3819 { yyDollar[1].subPartitionDefinitionOptionsUnion().Engine = yyDollar[2].partitionEngineUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() @@ -15225,7 +15253,7 @@ yydefault: case 692: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3819 +//line sql.y:3824 { yyDollar[1].subPartitionDefinitionOptionsUnion().DataDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() @@ -15234,7 +15262,7 @@ yydefault: case 693: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3824 +//line sql.y:3829 { yyDollar[1].subPartitionDefinitionOptionsUnion().IndexDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() @@ -15243,7 +15271,7 @@ yydefault: case 694: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3829 +//line sql.y:3834 { yyDollar[1].subPartitionDefinitionOptionsUnion().MaxRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() @@ -15252,7 +15280,7 @@ yydefault: case 695: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3834 +//line sql.y:3839 { yyDollar[1].subPartitionDefinitionOptionsUnion().MinRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() @@ -15261,7 +15289,7 @@ yydefault: case 696: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:3839 +//line sql.y:3844 { yyDollar[1].subPartitionDefinitionOptionsUnion().TableSpace = yyDollar[2].str yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() @@ -15270,7 +15298,7 @@ yydefault: case 697: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:3846 +//line sql.y:3851 { yyLOCAL = &PartitionValueRange{ Type: LessThanType, @@ -15281,7 +15309,7 @@ yydefault: case 698: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:3853 +//line sql.y:3858 { yyLOCAL = &PartitionValueRange{ Type: LessThanType, @@ -15292,7 +15320,7 @@ yydefault: case 699: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:3860 +//line sql.y:3865 { yyLOCAL = &PartitionValueRange{ Type: InType, @@ -15303,7 +15331,7 @@ yydefault: case 700: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3868 +//line sql.y:3873 { yyLOCAL = false } @@ -15311,7 +15339,7 @@ yydefault: case 701: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3872 +//line sql.y:3877 { yyLOCAL = true } @@ -15319,7 +15347,7 @@ yydefault: case 702: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionEngine -//line sql.y:3878 +//line sql.y:3883 { yyLOCAL = &PartitionEngine{Storage: yyDollar[1].booleanUnion(), Name: yyDollar[4].identifierCS.String()} } @@ -15327,7 +15355,7 @@ yydefault: case 703: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Literal -//line sql.y:3884 +//line sql.y:3889 { yyLOCAL = NewStrLiteral(yyDollar[3].str) } @@ -15335,7 +15363,7 @@ yydefault: case 704: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Literal -//line sql.y:3890 +//line sql.y:3895 { yyLOCAL = NewStrLiteral(yyDollar[4].str) } @@ -15343,7 +15371,7 @@ yydefault: case 705: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Literal -//line sql.y:3896 +//line sql.y:3901 { yyLOCAL = NewStrLiteral(yyDollar[4].str) } @@ -15351,7 +15379,7 @@ yydefault: case 706: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:3902 +//line sql.y:3907 { yyLOCAL = convertStringToInt(yyDollar[3].str) } @@ -15359,41 +15387,41 @@ yydefault: case 707: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:3908 +//line sql.y:3913 { yyLOCAL = convertStringToInt(yyDollar[3].str) } yyVAL.union = yyLOCAL case 708: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3914 +//line sql.y:3919 { yyVAL.str = yyDollar[3].identifierCS.String() } case 709: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinition -//line sql.y:3920 +//line sql.y:3925 { yyLOCAL = &PartitionDefinition{Name: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL case 710: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3926 +//line sql.y:3931 { yyVAL.str = "" } case 711: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3930 +//line sql.y:3935 { yyVAL.str = "" } case 712: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3936 +//line sql.y:3941 { yyLOCAL = &RenameTable{TablePairs: yyDollar[3].renameTablePairsUnion()} } @@ -15401,14 +15429,14 @@ yydefault: case 713: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*RenameTablePair -//line sql.y:3942 +//line sql.y:3947 { yyLOCAL = []*RenameTablePair{{FromTable: yyDollar[1].tableName, ToTable: yyDollar[3].tableName}} } yyVAL.union = yyLOCAL case 714: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3946 +//line sql.y:3951 { yySLICE := (*[]*RenameTablePair)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, &RenameTablePair{FromTable: yyDollar[3].tableName, ToTable: yyDollar[5].tableName}) @@ -15416,7 +15444,7 @@ yydefault: case 715: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3952 +//line sql.y:3957 { yyLOCAL = &DropTable{FromTables: yyDollar[6].tableNamesUnion(), IfExists: yyDollar[5].booleanUnion(), Comments: Comments(yyDollar[2].strs).Parsed(), Temp: yyDollar[3].booleanUnion()} } @@ -15424,7 +15452,7 @@ yydefault: case 716: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3956 +//line sql.y:3961 { // Change this to an alter statement if yyDollar[4].identifierCI.Lowered() == "primary" { @@ -15437,7 +15465,7 @@ yydefault: case 717: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3965 +//line sql.y:3970 { yyLOCAL = &DropView{FromTables: yyDollar[5].tableNamesUnion(), Comments: Comments(yyDollar[2].strs).Parsed(), IfExists: yyDollar[4].booleanUnion()} } @@ -15445,7 +15473,7 @@ yydefault: case 718: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3969 +//line sql.y:3974 { yyLOCAL = &DropDatabase{Comments: Comments(yyDollar[2].strs).Parsed(), DBName: yyDollar[5].identifierCS, IfExists: yyDollar[4].booleanUnion()} } @@ -15453,7 +15481,7 @@ yydefault: case 719: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3975 +//line sql.y:3980 { yyLOCAL = &TruncateTable{Table: yyDollar[3].tableName} } @@ -15461,7 +15489,7 @@ yydefault: case 720: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:3979 +//line sql.y:3984 { yyLOCAL = &TruncateTable{Table: yyDollar[2].tableName} } @@ -15469,7 +15497,7 @@ yydefault: case 721: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:3985 +//line sql.y:3990 { yyLOCAL = &Analyze{IsLocal: yyDollar[2].booleanUnion(), Table: yyDollar[4].tableName} } @@ -15477,7 +15505,7 @@ yydefault: case 722: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3991 +//line sql.y:3996 { yyLOCAL = &PurgeBinaryLogs{To: string(yyDollar[5].str)} } @@ -15485,7 +15513,7 @@ yydefault: case 723: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3995 +//line sql.y:4000 { yyLOCAL = &PurgeBinaryLogs{Before: string(yyDollar[5].str)} } @@ -15493,7 +15521,7 @@ yydefault: case 724: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4001 +//line sql.y:4006 { yyLOCAL = &Show{&ShowBasic{Command: Charset, Filter: yyDollar[3].showFilterUnion()}} } @@ -15501,7 +15529,7 @@ yydefault: case 725: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4005 +//line sql.y:4010 { yyLOCAL = &Show{&ShowBasic{Command: Collation, Filter: yyDollar[3].showFilterUnion()}} } @@ -15509,7 +15537,7 @@ yydefault: case 726: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:4009 +//line sql.y:4014 { yyLOCAL = &Show{&ShowBasic{Full: yyDollar[2].booleanUnion(), Command: Column, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].identifierCS, Filter: yyDollar[7].showFilterUnion()}} } @@ -15517,7 +15545,7 @@ yydefault: case 727: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4013 +//line sql.y:4018 { yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} } @@ -15525,7 +15553,7 @@ yydefault: case 728: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4017 +//line sql.y:4022 { yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} } @@ -15533,7 +15561,7 @@ yydefault: case 729: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4021 +//line sql.y:4026 { yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} } @@ -15541,7 +15569,7 @@ yydefault: case 730: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4025 +//line sql.y:4030 { yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} } @@ -15549,7 +15577,7 @@ yydefault: case 731: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4029 +//line sql.y:4034 { yyLOCAL = &Show{&ShowBasic{Command: Function, Filter: yyDollar[4].showFilterUnion()}} } @@ -15557,7 +15585,7 @@ yydefault: case 732: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:4033 +//line sql.y:4038 { yyLOCAL = &Show{&ShowBasic{Command: Index, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].identifierCS, Filter: yyDollar[7].showFilterUnion()}} } @@ -15565,7 +15593,7 @@ yydefault: case 733: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4037 +//line sql.y:4042 { yyLOCAL = &Show{&ShowBasic{Command: OpenTable, DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } @@ -15573,7 +15601,7 @@ yydefault: case 734: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4041 +//line sql.y:4046 { yyLOCAL = &Show{&ShowBasic{Command: Privilege}} } @@ -15581,7 +15609,7 @@ yydefault: case 735: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4045 +//line sql.y:4050 { yyLOCAL = &Show{&ShowBasic{Command: Procedure, Filter: yyDollar[4].showFilterUnion()}} } @@ -15589,7 +15617,7 @@ yydefault: case 736: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4049 +//line sql.y:4054 { yyLOCAL = &Show{&ShowBasic{Command: StatusSession, Filter: yyDollar[4].showFilterUnion()}} } @@ -15597,7 +15625,7 @@ yydefault: case 737: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4053 +//line sql.y:4058 { yyLOCAL = &Show{&ShowBasic{Command: StatusGlobal, Filter: yyDollar[4].showFilterUnion()}} } @@ -15605,7 +15633,7 @@ yydefault: case 738: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4057 +//line sql.y:4062 { yyLOCAL = &Show{&ShowBasic{Command: VariableSession, Filter: yyDollar[4].showFilterUnion()}} } @@ -15613,7 +15641,7 @@ yydefault: case 739: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4061 +//line sql.y:4066 { yyLOCAL = &Show{&ShowBasic{Command: VariableGlobal, Filter: yyDollar[4].showFilterUnion()}} } @@ -15621,7 +15649,7 @@ yydefault: case 740: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4065 +//line sql.y:4070 { yyLOCAL = &Show{&ShowBasic{Command: TableStatus, DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } @@ -15629,7 +15657,7 @@ yydefault: case 741: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4069 +//line sql.y:4074 { yyLOCAL = &Show{&ShowBasic{Command: Table, Full: yyDollar[2].booleanUnion(), DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } @@ -15637,7 +15665,7 @@ yydefault: case 742: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4073 +//line sql.y:4078 { yyLOCAL = &Show{&ShowBasic{Command: Trigger, DbName: yyDollar[3].identifierCS, Filter: yyDollar[4].showFilterUnion()}} } @@ -15645,7 +15673,7 @@ yydefault: case 743: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4077 +//line sql.y:4082 { yyLOCAL = &Show{&ShowCreate{Command: CreateDb, Op: yyDollar[4].tableName}} } @@ -15653,7 +15681,7 @@ yydefault: case 744: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4081 +//line sql.y:4086 { yyLOCAL = &Show{&ShowCreate{Command: CreateE, Op: yyDollar[4].tableName}} } @@ -15661,7 +15689,7 @@ yydefault: case 745: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4085 +//line sql.y:4090 { yyLOCAL = &Show{&ShowCreate{Command: CreateF, Op: yyDollar[4].tableName}} } @@ -15669,7 +15697,7 @@ yydefault: case 746: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4089 +//line sql.y:4094 { yyLOCAL = &Show{&ShowCreate{Command: CreateProc, Op: yyDollar[4].tableName}} } @@ -15677,7 +15705,7 @@ yydefault: case 747: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4093 +//line sql.y:4098 { yyLOCAL = &Show{&ShowCreate{Command: CreateTbl, Op: yyDollar[4].tableName}} } @@ -15685,7 +15713,7 @@ yydefault: case 748: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4097 +//line sql.y:4102 { yyLOCAL = &Show{&ShowCreate{Command: CreateTr, Op: yyDollar[4].tableName}} } @@ -15693,7 +15721,7 @@ yydefault: case 749: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4101 +//line sql.y:4106 { yyLOCAL = &Show{&ShowCreate{Command: CreateV, Op: yyDollar[4].tableName}} } @@ -15701,7 +15729,7 @@ yydefault: case 750: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4105 +//line sql.y:4110 { yyLOCAL = &Show{&ShowBasic{Command: Engines}} } @@ -15709,7 +15737,7 @@ yydefault: case 751: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4109 +//line sql.y:4114 { yyLOCAL = &Show{&ShowBasic{Command: Plugins}} } @@ -15717,7 +15745,7 @@ yydefault: case 752: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4113 +//line sql.y:4118 { yyLOCAL = &Show{&ShowBasic{Command: GtidExecGlobal, DbName: yyDollar[4].identifierCS}} } @@ -15725,7 +15753,7 @@ yydefault: case 753: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4117 +//line sql.y:4122 { yyLOCAL = &Show{&ShowBasic{Command: VGtidExecGlobal, DbName: yyDollar[4].identifierCS}} } @@ -15733,7 +15761,7 @@ yydefault: case 754: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4121 +//line sql.y:4126 { yyLOCAL = &Show{&ShowBasic{Command: VitessVariables, Filter: yyDollar[4].showFilterUnion()}} } @@ -15741,7 +15769,7 @@ yydefault: case 755: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4125 +//line sql.y:4130 { yyLOCAL = &Show{&ShowBasic{Command: VitessMigrations, Filter: yyDollar[4].showFilterUnion(), DbName: yyDollar[3].identifierCS}} } @@ -15749,7 +15777,7 @@ yydefault: case 756: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4129 +//line sql.y:4134 { yyLOCAL = &ShowMigrationLogs{UUID: string(yyDollar[3].str)} } @@ -15757,7 +15785,7 @@ yydefault: case 757: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4133 +//line sql.y:4138 { yyLOCAL = &ShowThrottledApps{} } @@ -15765,7 +15793,7 @@ yydefault: case 758: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4137 +//line sql.y:4142 { yyLOCAL = &Show{&ShowBasic{Command: VitessReplicationStatus, Filter: yyDollar[3].showFilterUnion()}} } @@ -15773,7 +15801,7 @@ yydefault: case 759: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4141 +//line sql.y:4146 { yyLOCAL = &ShowThrottlerStatus{} } @@ -15781,7 +15809,7 @@ yydefault: case 760: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4145 +//line sql.y:4150 { yyLOCAL = &Show{&ShowBasic{Command: VschemaTables}} } @@ -15789,7 +15817,7 @@ yydefault: case 761: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4149 +//line sql.y:4154 { yyLOCAL = &Show{&ShowBasic{Command: VschemaKeyspaces}} } @@ -15797,7 +15825,7 @@ yydefault: case 762: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4153 +//line sql.y:4158 { yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes}} } @@ -15805,7 +15833,7 @@ yydefault: case 763: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4157 +//line sql.y:4162 { yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes, Tbl: yyDollar[5].tableName}} } @@ -15813,7 +15841,7 @@ yydefault: case 764: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4161 +//line sql.y:4166 { yyLOCAL = &Show{&ShowBasic{Command: Warnings}} } @@ -15821,7 +15849,7 @@ yydefault: case 765: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4165 +//line sql.y:4170 { yyLOCAL = &Show{&ShowBasic{Command: VitessShards, Filter: yyDollar[3].showFilterUnion()}} } @@ -15829,7 +15857,7 @@ yydefault: case 766: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4169 +//line sql.y:4174 { yyLOCAL = &Show{&ShowBasic{Command: VitessTablets, Filter: yyDollar[3].showFilterUnion()}} } @@ -15837,7 +15865,7 @@ yydefault: case 767: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4173 +//line sql.y:4178 { yyLOCAL = &Show{&ShowBasic{Command: VitessTarget}} } @@ -15845,7 +15873,7 @@ yydefault: case 768: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4180 +//line sql.y:4185 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].identifierCI.String())}} } @@ -15853,7 +15881,7 @@ yydefault: case 769: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4184 +//line sql.y:4189 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} } @@ -15861,7 +15889,7 @@ yydefault: case 770: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4188 +//line sql.y:4193 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String()}} } @@ -15869,7 +15897,7 @@ yydefault: case 771: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4192 +//line sql.y:4197 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} } @@ -15877,7 +15905,7 @@ yydefault: case 772: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4196 +//line sql.y:4201 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} } @@ -15885,7 +15913,7 @@ yydefault: case 773: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4200 +//line sql.y:4205 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} } @@ -15893,7 +15921,7 @@ yydefault: case 774: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4204 +//line sql.y:4209 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} } @@ -15901,7 +15929,7 @@ yydefault: case 775: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4208 +//line sql.y:4213 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[3].str)}} } @@ -15909,27 +15937,27 @@ yydefault: case 776: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4212 +//line sql.y:4217 { yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} } yyVAL.union = yyLOCAL case 777: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4218 +//line sql.y:4223 { yyVAL.str = "" } case 778: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4222 +//line sql.y:4227 { yyVAL.str = "extended " } case 779: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4228 +//line sql.y:4233 { yyLOCAL = false } @@ -15937,45 +15965,45 @@ yydefault: case 780: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4232 +//line sql.y:4237 { yyLOCAL = true } yyVAL.union = yyLOCAL case 781: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4238 +//line sql.y:4243 { yyVAL.str = string(yyDollar[1].str) } case 782: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4242 +//line sql.y:4247 { yyVAL.str = string(yyDollar[1].str) } case 783: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4248 +//line sql.y:4253 { yyVAL.identifierCS = NewIdentifierCS("") } case 784: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4252 +//line sql.y:4257 { yyVAL.identifierCS = yyDollar[2].identifierCS } case 785: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4256 +//line sql.y:4261 { yyVAL.identifierCS = yyDollar[2].identifierCS } case 786: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4262 +//line sql.y:4267 { yyLOCAL = nil } @@ -15983,7 +16011,7 @@ yydefault: case 787: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4266 +//line sql.y:4271 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } @@ -15991,7 +16019,7 @@ yydefault: case 788: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4270 +//line sql.y:4275 { yyLOCAL = &ShowFilter{Filter: yyDollar[2].exprUnion()} } @@ -15999,7 +16027,7 @@ yydefault: case 789: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4276 +//line sql.y:4281 { yyLOCAL = nil } @@ -16007,45 +16035,45 @@ yydefault: case 790: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4280 +//line sql.y:4285 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } yyVAL.union = yyLOCAL case 791: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4286 +//line sql.y:4291 { yyVAL.empty = struct{}{} } case 792: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4290 +//line sql.y:4295 { yyVAL.empty = struct{}{} } case 793: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4294 +//line sql.y:4299 { yyVAL.empty = struct{}{} } case 794: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4300 +//line sql.y:4305 { yyVAL.str = string(yyDollar[1].str) } case 795: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4304 +//line sql.y:4309 { yyVAL.str = string(yyDollar[1].str) } case 796: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4310 +//line sql.y:4315 { yyLOCAL = &Use{DBName: yyDollar[2].identifierCS} } @@ -16053,7 +16081,7 @@ yydefault: case 797: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4314 +//line sql.y:4319 { yyLOCAL = &Use{DBName: IdentifierCS{v: ""}} } @@ -16061,39 +16089,39 @@ yydefault: case 798: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4318 +//line sql.y:4323 { yyLOCAL = &Use{DBName: NewIdentifierCS(yyDollar[2].identifierCS.String() + "@" + string(yyDollar[3].str))} } yyVAL.union = yyLOCAL case 799: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4325 +//line sql.y:4330 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } case 800: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4329 +//line sql.y:4334 { yyVAL.identifierCS = NewIdentifierCS("@" + string(yyDollar[1].str)) } case 801: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4333 +//line sql.y:4338 { yyVAL.identifierCS = NewIdentifierCS("@@" + string(yyDollar[1].str)) } case 802: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4337 +//line sql.y:4342 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } case 803: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4344 +//line sql.y:4349 { yyLOCAL = &Begin{} } @@ -16101,7 +16129,7 @@ yydefault: case 804: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4348 +//line sql.y:4353 { yyLOCAL = &Begin{TxAccessModes: yyDollar[3].txAccessModesUnion()} } @@ -16109,7 +16137,7 @@ yydefault: case 805: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4353 +//line sql.y:4358 { yyLOCAL = nil } @@ -16117,7 +16145,7 @@ yydefault: case 806: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4357 +//line sql.y:4362 { yyLOCAL = yyDollar[1].txAccessModesUnion() } @@ -16125,14 +16153,14 @@ yydefault: case 807: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4363 +//line sql.y:4368 { yyLOCAL = []TxAccessMode{yyDollar[1].txAccessModeUnion()} } yyVAL.union = yyLOCAL case 808: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4367 +//line sql.y:4372 { yySLICE := (*[]TxAccessMode)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].txAccessModeUnion()) @@ -16140,7 +16168,7 @@ yydefault: case 809: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4373 +//line sql.y:4378 { yyLOCAL = WithConsistentSnapshot } @@ -16148,7 +16176,7 @@ yydefault: case 810: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4377 +//line sql.y:4382 { yyLOCAL = ReadWrite } @@ -16156,7 +16184,7 @@ yydefault: case 811: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4381 +//line sql.y:4386 { yyLOCAL = ReadOnly } @@ -16164,7 +16192,7 @@ yydefault: case 812: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4388 +//line sql.y:4393 { yyLOCAL = &Commit{} } @@ -16172,7 +16200,7 @@ yydefault: case 813: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4394 +//line sql.y:4399 { yyLOCAL = &Rollback{} } @@ -16180,39 +16208,39 @@ yydefault: case 814: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4398 +//line sql.y:4403 { yyLOCAL = &SRollback{Name: yyDollar[5].identifierCI} } yyVAL.union = yyLOCAL case 815: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4403 +//line sql.y:4408 { yyVAL.empty = struct{}{} } case 816: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4405 +//line sql.y:4410 { yyVAL.empty = struct{}{} } case 817: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4408 +//line sql.y:4413 { yyVAL.empty = struct{}{} } case 818: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4410 +//line sql.y:4415 { yyVAL.empty = struct{}{} } case 819: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4414 +//line sql.y:4419 { yyLOCAL = &Savepoint{Name: yyDollar[2].identifierCI} } @@ -16220,7 +16248,7 @@ yydefault: case 820: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4420 +//line sql.y:4425 { yyLOCAL = &Release{Name: yyDollar[3].identifierCI} } @@ -16228,7 +16256,7 @@ yydefault: case 821: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4425 +//line sql.y:4430 { yyLOCAL = EmptyType } @@ -16236,7 +16264,7 @@ yydefault: case 822: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4429 +//line sql.y:4434 { yyLOCAL = JSONType } @@ -16244,7 +16272,7 @@ yydefault: case 823: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4433 +//line sql.y:4438 { yyLOCAL = TreeType } @@ -16252,7 +16280,7 @@ yydefault: case 824: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4437 +//line sql.y:4442 { yyLOCAL = TraditionalType } @@ -16260,7 +16288,7 @@ yydefault: case 825: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4441 +//line sql.y:4446 { yyLOCAL = AnalyzeType } @@ -16268,7 +16296,7 @@ yydefault: case 826: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4446 +//line sql.y:4451 { yyLOCAL = PlanVExplainType } @@ -16276,7 +16304,7 @@ yydefault: case 827: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4450 +//line sql.y:4455 { yyLOCAL = PlanVExplainType } @@ -16284,7 +16312,7 @@ yydefault: case 828: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4454 +//line sql.y:4459 { yyLOCAL = AllVExplainType } @@ -16292,33 +16320,33 @@ yydefault: case 829: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4458 +//line sql.y:4463 { yyLOCAL = QueriesVExplainType } yyVAL.union = yyLOCAL case 830: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4464 +//line sql.y:4469 { yyVAL.str = yyDollar[1].str } case 831: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4468 +//line sql.y:4473 { yyVAL.str = yyDollar[1].str } case 832: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4472 +//line sql.y:4477 { yyVAL.str = yyDollar[1].str } case 833: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4478 +//line sql.y:4483 { yyLOCAL = yyDollar[1].selStmtUnion() } @@ -16326,7 +16354,7 @@ yydefault: case 834: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4482 +//line sql.y:4487 { yyLOCAL = yyDollar[1].statementUnion() } @@ -16334,7 +16362,7 @@ yydefault: case 835: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4486 +//line sql.y:4491 { yyLOCAL = yyDollar[1].statementUnion() } @@ -16342,33 +16370,33 @@ yydefault: case 836: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4490 +//line sql.y:4495 { yyLOCAL = yyDollar[1].statementUnion() } yyVAL.union = yyLOCAL case 837: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4495 +//line sql.y:4500 { yyVAL.str = "" } case 838: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4499 +//line sql.y:4504 { yyVAL.str = yyDollar[1].identifierCI.val } case 839: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4503 +//line sql.y:4508 { yyVAL.str = encodeSQLString(yyDollar[1].str) } case 840: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4509 +//line sql.y:4514 { yyLOCAL = &ExplainTab{Table: yyDollar[3].tableName, Wild: yyDollar[4].str} } @@ -16376,7 +16404,7 @@ yydefault: case 841: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4513 +//line sql.y:4518 { yyLOCAL = &ExplainStmt{Type: yyDollar[3].explainTypeUnion(), Statement: yyDollar[4].statementUnion(), Comments: Comments(yyDollar[2].strs).Parsed()} } @@ -16384,7 +16412,7 @@ yydefault: case 842: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4519 +//line sql.y:4524 { yyLOCAL = &VExplainStmt{Type: yyDollar[3].vexplainTypeUnion(), Statement: yyDollar[4].statementUnion(), Comments: Comments(yyDollar[2].strs).Parsed()} } @@ -16392,7 +16420,7 @@ yydefault: case 843: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4525 +//line sql.y:4530 { yyLOCAL = &OtherAdmin{} } @@ -16400,7 +16428,7 @@ yydefault: case 844: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4529 +//line sql.y:4534 { yyLOCAL = &OtherAdmin{} } @@ -16408,7 +16436,7 @@ yydefault: case 845: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4535 +//line sql.y:4540 { yyLOCAL = &LockTables{Tables: yyDollar[3].tableAndLockTypesUnion()} } @@ -16416,14 +16444,14 @@ yydefault: case 846: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableAndLockTypes -//line sql.y:4541 +//line sql.y:4546 { yyLOCAL = TableAndLockTypes{yyDollar[1].tableAndLockTypeUnion()} } yyVAL.union = yyLOCAL case 847: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4545 +//line sql.y:4550 { yySLICE := (*TableAndLockTypes)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableAndLockTypeUnion()) @@ -16431,7 +16459,7 @@ yydefault: case 848: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *TableAndLockType -//line sql.y:4551 +//line sql.y:4556 { yyLOCAL = &TableAndLockType{Table: yyDollar[1].aliasedTableNameUnion(), Lock: yyDollar[2].lockTypeUnion()} } @@ -16439,7 +16467,7 @@ yydefault: case 849: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:4557 +//line sql.y:4562 { yyLOCAL = Read } @@ -16447,7 +16475,7 @@ yydefault: case 850: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:4561 +//line sql.y:4566 { yyLOCAL = ReadLocal } @@ -16455,7 +16483,7 @@ yydefault: case 851: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:4565 +//line sql.y:4570 { yyLOCAL = Write } @@ -16463,7 +16491,7 @@ yydefault: case 852: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:4569 +//line sql.y:4574 { yyLOCAL = LowPriorityWrite } @@ -16471,7 +16499,7 @@ yydefault: case 853: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4575 +//line sql.y:4580 { yyLOCAL = &UnlockTables{} } @@ -16479,7 +16507,7 @@ yydefault: case 854: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4581 +//line sql.y:4586 { yyLOCAL = &RevertMigration{Comments: Comments(yyDollar[2].strs).Parsed(), UUID: string(yyDollar[4].str)} } @@ -16487,7 +16515,7 @@ yydefault: case 855: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4587 +//line sql.y:4592 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), FlushOptions: yyDollar[3].strs} } @@ -16495,7 +16523,7 @@ yydefault: case 856: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4591 +//line sql.y:4596 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion()} } @@ -16503,7 +16531,7 @@ yydefault: case 857: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:4595 +//line sql.y:4600 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), WithLock: true} } @@ -16511,7 +16539,7 @@ yydefault: case 858: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4599 +//line sql.y:4604 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion()} } @@ -16519,7 +16547,7 @@ yydefault: case 859: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:4603 +//line sql.y:4608 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), WithLock: true} } @@ -16527,99 +16555,99 @@ yydefault: case 860: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:4607 +//line sql.y:4612 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), ForExport: true} } yyVAL.union = yyLOCAL case 861: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4613 +//line sql.y:4618 { yyVAL.strs = []string{yyDollar[1].str} } case 862: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4617 +//line sql.y:4622 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[3].str) } case 863: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4623 +//line sql.y:4628 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 864: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4627 +//line sql.y:4632 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 865: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4631 +//line sql.y:4636 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 866: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4635 +//line sql.y:4640 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 867: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4639 +//line sql.y:4644 { yyVAL.str = string(yyDollar[1].str) } case 868: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4643 +//line sql.y:4648 { yyVAL.str = string(yyDollar[1].str) } case 869: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4647 +//line sql.y:4652 { yyVAL.str = string(yyDollar[1].str) } case 870: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4651 +//line sql.y:4656 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyDollar[3].str } case 871: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4655 +//line sql.y:4660 { yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 872: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4659 +//line sql.y:4664 { yyVAL.str = string(yyDollar[1].str) } case 873: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4663 +//line sql.y:4668 { yyVAL.str = string(yyDollar[1].str) } case 874: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4667 +//line sql.y:4672 { yyVAL.str = string(yyDollar[1].str) } case 875: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4672 +//line sql.y:4677 { yyLOCAL = false } @@ -16627,7 +16655,7 @@ yydefault: case 876: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4676 +//line sql.y:4681 { yyLOCAL = true } @@ -16635,52 +16663,52 @@ yydefault: case 877: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4680 +//line sql.y:4685 { yyLOCAL = true } yyVAL.union = yyLOCAL case 878: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4685 +//line sql.y:4690 { yyVAL.str = "" } case 879: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4689 +//line sql.y:4694 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String() } case 880: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4694 +//line sql.y:4699 { setAllowComments(yylex, true) } case 881: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4698 +//line sql.y:4703 { yyVAL.strs = yyDollar[2].strs setAllowComments(yylex, false) } case 882: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4704 +//line sql.y:4709 { yyVAL.strs = nil } case 883: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4708 +//line sql.y:4713 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[2].str) } case 884: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4714 +//line sql.y:4719 { yyLOCAL = true } @@ -16688,7 +16716,7 @@ yydefault: case 885: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4718 +//line sql.y:4723 { yyLOCAL = false } @@ -16696,33 +16724,33 @@ yydefault: case 886: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4722 +//line sql.y:4727 { yyLOCAL = true } yyVAL.union = yyLOCAL case 887: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4727 +//line sql.y:4732 { yyVAL.str = "" } case 888: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4731 +//line sql.y:4736 { yyVAL.str = SQLNoCacheStr } case 889: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4735 +//line sql.y:4740 { yyVAL.str = SQLCacheStr } case 890: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4740 +//line sql.y:4745 { yyLOCAL = false } @@ -16730,7 +16758,7 @@ yydefault: case 891: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4744 +//line sql.y:4749 { yyLOCAL = true } @@ -16738,7 +16766,7 @@ yydefault: case 892: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4748 +//line sql.y:4753 { yyLOCAL = true } @@ -16746,7 +16774,7 @@ yydefault: case 893: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4754 +//line sql.y:4759 { yyLOCAL = &PrepareStmt{Name: yyDollar[3].identifierCI, Comments: Comments(yyDollar[2].strs).Parsed(), Statement: yyDollar[5].exprUnion()} } @@ -16754,7 +16782,7 @@ yydefault: case 894: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4758 +//line sql.y:4763 { yyLOCAL = &PrepareStmt{ Name: yyDollar[3].identifierCI, @@ -16766,7 +16794,7 @@ yydefault: case 895: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4768 +//line sql.y:4773 { yyLOCAL = &ExecuteStmt{Name: yyDollar[3].identifierCI, Comments: Comments(yyDollar[2].strs).Parsed(), Arguments: yyDollar[4].variablesUnion()} } @@ -16774,7 +16802,7 @@ yydefault: case 896: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*Variable -//line sql.y:4773 +//line sql.y:4778 { yyLOCAL = nil } @@ -16782,7 +16810,7 @@ yydefault: case 897: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []*Variable -//line sql.y:4777 +//line sql.y:4782 { yyLOCAL = yyDollar[2].variablesUnion() } @@ -16790,7 +16818,7 @@ yydefault: case 898: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4783 +//line sql.y:4788 { yyLOCAL = &DeallocateStmt{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[4].identifierCI} } @@ -16798,88 +16826,88 @@ yydefault: case 899: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4787 +//line sql.y:4792 { yyLOCAL = &DeallocateStmt{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[4].identifierCI} } yyVAL.union = yyLOCAL case 900: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4792 +//line sql.y:4797 { yyVAL.strs = nil } case 901: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4796 +//line sql.y:4801 { yyVAL.strs = yyDollar[1].strs } case 902: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4802 +//line sql.y:4807 { yyVAL.strs = []string{yyDollar[1].str} } case 903: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4806 +//line sql.y:4811 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[2].str) } case 904: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4812 +//line sql.y:4817 { yyVAL.str = SQLNoCacheStr } case 905: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4816 +//line sql.y:4821 { yyVAL.str = SQLCacheStr } case 906: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4820 +//line sql.y:4825 { yyVAL.str = DistinctStr } case 907: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4824 +//line sql.y:4829 { yyVAL.str = DistinctStr } case 908: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4828 +//line sql.y:4833 { yyVAL.str = StraightJoinHint } case 909: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4832 +//line sql.y:4837 { yyVAL.str = SQLCalcFoundRowsStr } case 910: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4836 +//line sql.y:4841 { yyVAL.str = AllStr // These are not picked up by NewSelect, and so ALL will be dropped. But this is OK, since it's redundant anyway } case 911: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExprs -//line sql.y:4842 +//line sql.y:4847 { yyLOCAL = SelectExprs{yyDollar[1].selectExprUnion()} } yyVAL.union = yyLOCAL case 912: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4846 +//line sql.y:4851 { yySLICE := (*SelectExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].selectExprUnion()) @@ -16887,7 +16915,7 @@ yydefault: case 913: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4852 +//line sql.y:4857 { yyLOCAL = &StarExpr{} } @@ -16895,7 +16923,7 @@ yydefault: case 914: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4856 +//line sql.y:4861 { yyLOCAL = &AliasedExpr{Expr: yyDollar[1].exprUnion(), As: yyDollar[2].identifierCI} } @@ -16903,7 +16931,7 @@ yydefault: case 915: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4860 +//line sql.y:4865 { yyLOCAL = &StarExpr{TableName: TableName{Name: yyDollar[1].identifierCS}} } @@ -16911,39 +16939,39 @@ yydefault: case 916: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:4864 +//line sql.y:4869 { yyLOCAL = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}} } yyVAL.union = yyLOCAL case 917: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4869 +//line sql.y:4874 { yyVAL.identifierCI = IdentifierCI{} } case 918: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4873 +//line sql.y:4878 { yyVAL.identifierCI = yyDollar[1].identifierCI } case 919: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4877 +//line sql.y:4882 { yyVAL.identifierCI = yyDollar[2].identifierCI } case 921: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4884 +//line sql.y:4889 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } case 922: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4889 +//line sql.y:4894 { yyLOCAL = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewIdentifierCS("dual")}}} } @@ -16951,7 +16979,7 @@ yydefault: case 923: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4893 +//line sql.y:4898 { yyLOCAL = yyDollar[1].tableExprsUnion() } @@ -16959,7 +16987,7 @@ yydefault: case 924: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4899 +//line sql.y:4904 { yyLOCAL = yyDollar[2].tableExprsUnion() } @@ -16967,14 +16995,14 @@ yydefault: case 925: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:4905 +//line sql.y:4910 { yyLOCAL = TableExprs{yyDollar[1].tableExprUnion()} } yyVAL.union = yyLOCAL case 926: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4909 +//line sql.y:4914 { yySLICE := (*TableExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableExprUnion()) @@ -16982,7 +17010,7 @@ yydefault: case 929: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4919 +//line sql.y:4924 { yyLOCAL = yyDollar[1].aliasedTableNameUnion() } @@ -16990,7 +17018,7 @@ yydefault: case 930: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4923 +//line sql.y:4928 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].derivedTableUnion(), As: yyDollar[3].identifierCS, Columns: yyDollar[4].columnsUnion()} } @@ -16998,7 +17026,7 @@ yydefault: case 931: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4927 +//line sql.y:4932 { yyLOCAL = &ParenTableExpr{Exprs: yyDollar[2].tableExprsUnion()} } @@ -17006,7 +17034,7 @@ yydefault: case 932: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:4931 +//line sql.y:4936 { yyLOCAL = yyDollar[1].tableExprUnion() } @@ -17014,7 +17042,7 @@ yydefault: case 933: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:4937 +//line sql.y:4942 { yyLOCAL = &DerivedTable{Lateral: false, Select: yyDollar[1].selStmtUnion()} } @@ -17022,7 +17050,7 @@ yydefault: case 934: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:4941 +//line sql.y:4946 { yyLOCAL = &DerivedTable{Lateral: true, Select: yyDollar[2].selStmtUnion()} } @@ -17030,7 +17058,7 @@ yydefault: case 935: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:4947 +//line sql.y:4952 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].identifierCS, Hints: yyDollar[3].indexHintsUnion()} } @@ -17038,7 +17066,7 @@ yydefault: case 936: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:4951 +//line sql.y:4956 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitionsUnion(), As: yyDollar[6].identifierCS, Hints: yyDollar[7].indexHintsUnion()} } @@ -17046,7 +17074,7 @@ yydefault: case 937: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:4956 +//line sql.y:4961 { yyLOCAL = nil } @@ -17054,7 +17082,7 @@ yydefault: case 938: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:4960 +//line sql.y:4965 { yyLOCAL = yyDollar[2].columnsUnion() } @@ -17062,7 +17090,7 @@ yydefault: case 939: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:4965 +//line sql.y:4970 { yyLOCAL = nil } @@ -17070,7 +17098,7 @@ yydefault: case 940: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4969 +//line sql.y:4974 { yyLOCAL = yyDollar[1].columnsUnion() } @@ -17078,14 +17106,14 @@ yydefault: case 941: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4975 +//line sql.y:4980 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL case 942: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4979 +//line sql.y:4984 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) @@ -17093,14 +17121,14 @@ yydefault: case 943: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*Variable -//line sql.y:4985 +//line sql.y:4990 { yyLOCAL = []*Variable{yyDollar[1].variableUnion()} } yyVAL.union = yyLOCAL case 944: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4989 +//line sql.y:4994 { yySLICE := (*[]*Variable)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].variableUnion()) @@ -17108,7 +17136,7 @@ yydefault: case 945: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4995 +//line sql.y:5000 { yyLOCAL = Columns{yyDollar[1].identifierCI} } @@ -17116,21 +17144,21 @@ yydefault: case 946: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4999 +//line sql.y:5004 { yyLOCAL = Columns{NewIdentifierCI(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL case 947: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5003 +//line sql.y:5008 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } case 948: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5007 +//line sql.y:5012 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, NewIdentifierCI(string(yyDollar[3].str))) @@ -17138,14 +17166,14 @@ yydefault: case 949: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Partitions -//line sql.y:5013 +//line sql.y:5018 { yyLOCAL = Partitions{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL case 950: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5017 +//line sql.y:5022 { yySLICE := (*Partitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) @@ -17153,7 +17181,7 @@ yydefault: case 951: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5030 +//line sql.y:5035 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } @@ -17161,7 +17189,7 @@ yydefault: case 952: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5034 +//line sql.y:5039 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } @@ -17169,7 +17197,7 @@ yydefault: case 953: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5038 +//line sql.y:5043 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } @@ -17177,87 +17205,87 @@ yydefault: case 954: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5042 +//line sql.y:5047 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion()} } yyVAL.union = yyLOCAL case 955: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5048 +//line sql.y:5053 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } case 956: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:5050 +//line sql.y:5055 { yyVAL.joinCondition = &JoinCondition{Using: yyDollar[3].columnsUnion()} } case 957: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5054 +//line sql.y:5059 { yyVAL.joinCondition = &JoinCondition{} } case 958: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5056 +//line sql.y:5061 { yyVAL.joinCondition = yyDollar[1].joinCondition } case 959: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5060 +//line sql.y:5065 { yyVAL.joinCondition = &JoinCondition{} } case 960: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5062 +//line sql.y:5067 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } case 961: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5065 +//line sql.y:5070 { yyVAL.empty = struct{}{} } case 962: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5067 +//line sql.y:5072 { yyVAL.empty = struct{}{} } case 963: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5070 +//line sql.y:5075 { yyVAL.identifierCS = NewIdentifierCS("") } case 964: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5074 +//line sql.y:5079 { yyVAL.identifierCS = yyDollar[1].identifierCS } case 965: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5078 +//line sql.y:5083 { yyVAL.identifierCS = yyDollar[2].identifierCS } case 967: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5085 +//line sql.y:5090 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } case 968: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5091 +//line sql.y:5096 { yyLOCAL = NormalJoinType } @@ -17265,7 +17293,7 @@ yydefault: case 969: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5095 +//line sql.y:5100 { yyLOCAL = NormalJoinType } @@ -17273,7 +17301,7 @@ yydefault: case 970: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5099 +//line sql.y:5104 { yyLOCAL = NormalJoinType } @@ -17281,7 +17309,7 @@ yydefault: case 971: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5105 +//line sql.y:5110 { yyLOCAL = StraightJoinType } @@ -17289,7 +17317,7 @@ yydefault: case 972: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5111 +//line sql.y:5116 { yyLOCAL = LeftJoinType } @@ -17297,7 +17325,7 @@ yydefault: case 973: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5115 +//line sql.y:5120 { yyLOCAL = LeftJoinType } @@ -17305,7 +17333,7 @@ yydefault: case 974: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5119 +//line sql.y:5124 { yyLOCAL = RightJoinType } @@ -17313,7 +17341,7 @@ yydefault: case 975: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5123 +//line sql.y:5128 { yyLOCAL = RightJoinType } @@ -17321,7 +17349,7 @@ yydefault: case 976: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5129 +//line sql.y:5134 { yyLOCAL = NaturalJoinType } @@ -17329,7 +17357,7 @@ yydefault: case 977: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5133 +//line sql.y:5138 { if yyDollar[2].joinTypeUnion() == LeftJoinType { yyLOCAL = NaturalLeftJoinType @@ -17340,38 +17368,38 @@ yydefault: yyVAL.union = yyLOCAL case 978: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5143 +//line sql.y:5148 { yyVAL.tableName = yyDollar[2].tableName } case 979: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5147 +//line sql.y:5152 { yyVAL.tableName = yyDollar[1].tableName } case 980: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5153 +//line sql.y:5158 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } case 981: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5157 +//line sql.y:5162 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS} } case 982: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5163 +//line sql.y:5168 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } case 983: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5168 +//line sql.y:5173 { yyLOCAL = nil } @@ -17379,7 +17407,7 @@ yydefault: case 984: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5172 +//line sql.y:5177 { yyLOCAL = yyDollar[1].indexHintsUnion() } @@ -17387,14 +17415,14 @@ yydefault: case 985: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5178 +//line sql.y:5183 { yyLOCAL = IndexHints{yyDollar[1].indexHintUnion()} } yyVAL.union = yyLOCAL case 986: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5182 +//line sql.y:5187 { yySLICE := (*IndexHints)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].indexHintUnion()) @@ -17402,7 +17430,7 @@ yydefault: case 987: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5188 +//line sql.y:5193 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } @@ -17410,7 +17438,7 @@ yydefault: case 988: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5192 +//line sql.y:5197 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion()} } @@ -17418,7 +17446,7 @@ yydefault: case 989: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5196 +//line sql.y:5201 { yyLOCAL = &IndexHint{Type: IgnoreOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } @@ -17426,7 +17454,7 @@ yydefault: case 990: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5200 +//line sql.y:5205 { yyLOCAL = &IndexHint{Type: ForceOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } @@ -17434,7 +17462,7 @@ yydefault: case 991: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5204 +//line sql.y:5209 { yyLOCAL = &IndexHint{Type: UseVindexOp, Indexes: yyDollar[4].columnsUnion()} } @@ -17442,7 +17470,7 @@ yydefault: case 992: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5208 +//line sql.y:5213 { yyLOCAL = &IndexHint{Type: IgnoreVindexOp, Indexes: yyDollar[4].columnsUnion()} } @@ -17450,7 +17478,7 @@ yydefault: case 993: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5213 +//line sql.y:5218 { yyLOCAL = NoForType } @@ -17458,7 +17486,7 @@ yydefault: case 994: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5217 +//line sql.y:5222 { yyLOCAL = JoinForType } @@ -17466,7 +17494,7 @@ yydefault: case 995: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5221 +//line sql.y:5226 { yyLOCAL = OrderByForType } @@ -17474,7 +17502,7 @@ yydefault: case 996: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5225 +//line sql.y:5230 { yyLOCAL = GroupByForType } @@ -17482,7 +17510,7 @@ yydefault: case 997: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:5231 +//line sql.y:5236 { yyLOCAL = nil } @@ -17490,7 +17518,7 @@ yydefault: case 998: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5235 +//line sql.y:5240 { yyLOCAL = yyDollar[2].exprUnion() } @@ -17498,7 +17526,7 @@ yydefault: case 999: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5242 +//line sql.y:5247 { yyLOCAL = &OrExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } @@ -17506,7 +17534,7 @@ yydefault: case 1000: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5246 +//line sql.y:5251 { yyLOCAL = &XorExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } @@ -17514,7 +17542,7 @@ yydefault: case 1001: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5250 +//line sql.y:5255 { yyLOCAL = &AndExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } @@ -17522,7 +17550,7 @@ yydefault: case 1002: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5254 +//line sql.y:5259 { yyLOCAL = &NotExpr{Expr: yyDollar[2].exprUnion()} } @@ -17530,7 +17558,7 @@ yydefault: case 1003: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5258 +//line sql.y:5263 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].isExprOperatorUnion()} } @@ -17538,7 +17566,7 @@ yydefault: case 1004: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5262 +//line sql.y:5267 { yyLOCAL = yyDollar[1].exprUnion() } @@ -17546,7 +17574,7 @@ yydefault: case 1005: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5266 +//line sql.y:5271 { yyLOCAL = &AssignmentExpr{Left: yyDollar[1].variableUnion(), Right: yyDollar[3].exprUnion()} } @@ -17554,25 +17582,25 @@ yydefault: case 1006: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5270 +//line sql.y:5275 { yyLOCAL = &MemberOfExpr{Value: yyDollar[1].exprUnion(), JSONArr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1007: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5276 +//line sql.y:5281 { } case 1008: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5279 +//line sql.y:5284 { } case 1009: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5284 +//line sql.y:5289 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNullOp} } @@ -17580,7 +17608,7 @@ yydefault: case 1010: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5288 +//line sql.y:5293 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNotNullOp} } @@ -17588,393 +17616,417 @@ yydefault: case 1011: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5292 +//line sql.y:5297 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1012: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL Expr +//line sql.y:5301 + { + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: Any, Right: yyDollar[4].subqueryUnion()} + } + yyVAL.union = yyLOCAL + case 1013: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL Expr +//line sql.y:5305 + { + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: Any, Right: yyDollar[4].subqueryUnion()} + } + yyVAL.union = yyLOCAL + case 1014: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL Expr +//line sql.y:5309 + { + yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: All, Right: yyDollar[4].subqueryUnion()} + } + yyVAL.union = yyLOCAL + case 1015: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5296 +//line sql.y:5313 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1013: + case 1016: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5302 +//line sql.y:5319 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: InOp, Right: yyDollar[3].colTupleUnion()} } yyVAL.union = yyLOCAL - case 1014: + case 1017: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5306 +//line sql.y:5323 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotInOp, Right: yyDollar[4].colTupleUnion()} } yyVAL.union = yyLOCAL - case 1015: + case 1018: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5310 +//line sql.y:5327 { yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: true, From: yyDollar[3].exprUnion(), To: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1016: + case 1019: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5314 +//line sql.y:5331 { yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: false, From: yyDollar[4].exprUnion(), To: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1017: + case 1020: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5318 +//line sql.y:5335 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1018: + case 1021: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5322 +//line sql.y:5339 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1019: + case 1022: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5326 +//line sql.y:5343 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion(), Escape: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1020: + case 1023: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5330 +//line sql.y:5347 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion(), Escape: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1021: + case 1024: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5334 +//line sql.y:5351 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: RegexpOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1022: + case 1025: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5338 +//line sql.y:5355 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotRegexpOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1023: + case 1026: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5342 +//line sql.y:5359 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1024: + case 1027: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5348 +//line sql.y:5365 { } - case 1025: + case 1028: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5351 +//line sql.y:5368 { } - case 1026: + case 1029: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5357 +//line sql.y:5374 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitOrOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1027: + case 1030: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5361 +//line sql.y:5378 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitAndOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1028: + case 1031: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5365 +//line sql.y:5382 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftLeftOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1029: + case 1032: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5369 +//line sql.y:5386 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftRightOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1030: + case 1033: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5373 +//line sql.y:5390 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: PlusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1031: + case 1034: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5377 +//line sql.y:5394 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MinusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1032: + case 1035: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5381 +//line sql.y:5398 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAdd, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1033: + case 1036: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5385 +//line sql.y:5402 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinarySub, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1034: + case 1037: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5389 +//line sql.y:5406 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MultOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1035: + case 1038: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5393 +//line sql.y:5410 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: DivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1036: + case 1039: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5397 +//line sql.y:5414 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1037: + case 1040: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5401 +//line sql.y:5418 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: IntDivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1038: + case 1041: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5405 +//line sql.y:5422 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1039: + case 1042: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5409 +//line sql.y:5426 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitXorOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1040: + case 1043: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5413 +//line sql.y:5430 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1041: + case 1044: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5419 +//line sql.y:5436 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1042: + case 1045: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5423 +//line sql.y:5440 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1043: + case 1046: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5427 +//line sql.y:5444 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1044: + case 1047: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5431 +//line sql.y:5448 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1045: + case 1048: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5435 +//line sql.y:5452 { yyLOCAL = &CollateExpr{Expr: yyDollar[1].exprUnion(), Collation: yyDollar[3].str} } yyVAL.union = yyLOCAL - case 1046: + case 1049: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5439 +//line sql.y:5456 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1047: + case 1050: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5443 +//line sql.y:5460 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1048: + case 1051: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5447 +//line sql.y:5464 { yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL - case 1049: + case 1052: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5451 +//line sql.y:5468 { yyLOCAL = yyDollar[2].exprUnion() // TODO: do we really want to ignore unary '+' before any kind of literals? } yyVAL.union = yyLOCAL - case 1050: + case 1053: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5455 +//line sql.y:5472 { yyLOCAL = &UnaryExpr{Operator: UMinusOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1051: + case 1054: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5459 +//line sql.y:5476 { yyLOCAL = &UnaryExpr{Operator: TildaOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1052: + case 1055: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5463 +//line sql.y:5480 { yyLOCAL = &UnaryExpr{Operator: BangOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1053: + case 1056: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5467 +//line sql.y:5484 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 1054: + case 1057: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5471 +//line sql.y:5488 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1055: + case 1058: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5475 +//line sql.y:5492 { yyLOCAL = &ExistsExpr{Subquery: yyDollar[2].subqueryUnion()} } yyVAL.union = yyLOCAL - case 1056: + case 1059: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:5479 +//line sql.y:5496 { yyLOCAL = &MatchExpr{Columns: yyDollar[2].colNamesUnion(), Expr: yyDollar[5].exprUnion(), Option: yyDollar[6].matchExprOptionUnion()} } yyVAL.union = yyLOCAL - case 1057: + case 1060: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:5483 +//line sql.y:5500 { yyLOCAL = &CastExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion(), Array: yyDollar[6].booleanUnion()} } yyVAL.union = yyLOCAL - case 1058: + case 1061: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5487 +//line sql.y:5504 { yyLOCAL = &ConvertExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1059: + case 1062: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5491 +//line sql.y:5508 { yyLOCAL = &ConvertUsingExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].str} } yyVAL.union = yyLOCAL - case 1060: + case 1063: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5495 +//line sql.y:5512 { // From: https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#operator_binary // To convert a string expression to a binary string, these constructs are equivalent: @@ -17983,3194 +18035,3202 @@ yydefault: yyLOCAL = &ConvertExpr{Expr: yyDollar[2].exprUnion(), Type: &ConvertType{Type: yyDollar[1].str}} } yyVAL.union = yyLOCAL - case 1061: + case 1064: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5503 +//line sql.y:5520 { yyLOCAL = &Default{ColName: yyDollar[2].str} } yyVAL.union = yyLOCAL - case 1062: + case 1065: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5507 +//line sql.y:5524 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAddLeft, Date: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion(), Interval: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1063: + case 1066: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5511 +//line sql.y:5528 { yyLOCAL = &IntervalFuncExpr{Expr: yyDollar[3].exprUnion(), Exprs: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1064: + case 1067: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5515 +//line sql.y:5532 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: JSONExtractOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1065: + case 1068: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5519 +//line sql.y:5536 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: JSONUnquoteExtractOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1066: + case 1069: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5525 +//line sql.y:5542 { yyLOCAL = yyDollar[1].colNamesUnion() } yyVAL.union = yyLOCAL - case 1067: + case 1070: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5529 +//line sql.y:5546 { yyLOCAL = yyDollar[2].colNamesUnion() } yyVAL.union = yyLOCAL - case 1068: + case 1071: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5535 +//line sql.y:5552 { yyLOCAL = []*ColName{yyDollar[1].colNameUnion()} } yyVAL.union = yyLOCAL - case 1069: + case 1072: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5539 +//line sql.y:5556 { yySLICE := (*[]*ColName)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colNameUnion()) } - case 1070: + case 1073: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:5545 +//line sql.y:5562 { yyLOCAL = BothTrimType } yyVAL.union = yyLOCAL - case 1071: + case 1074: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:5549 +//line sql.y:5566 { yyLOCAL = LeadingTrimType } yyVAL.union = yyLOCAL - case 1072: + case 1075: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:5553 +//line sql.y:5570 { yyLOCAL = TrailingTrimType } yyVAL.union = yyLOCAL - case 1073: + case 1076: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FrameUnitType -//line sql.y:5559 +//line sql.y:5576 { yyLOCAL = FrameRowsType } yyVAL.union = yyLOCAL - case 1074: + case 1077: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FrameUnitType -//line sql.y:5563 +//line sql.y:5580 { yyLOCAL = FrameRangeType } yyVAL.union = yyLOCAL - case 1075: + case 1078: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5570 +//line sql.y:5587 { yyLOCAL = CumeDistExprType } yyVAL.union = yyLOCAL - case 1076: + case 1079: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5574 +//line sql.y:5591 { yyLOCAL = DenseRankExprType } yyVAL.union = yyLOCAL - case 1077: + case 1080: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5578 +//line sql.y:5595 { yyLOCAL = PercentRankExprType } yyVAL.union = yyLOCAL - case 1078: + case 1081: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5582 +//line sql.y:5599 { yyLOCAL = RankExprType } yyVAL.union = yyLOCAL - case 1079: + case 1082: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:5586 +//line sql.y:5603 { yyLOCAL = RowNumberExprType } yyVAL.union = yyLOCAL - case 1080: + case 1083: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5592 +//line sql.y:5609 { yyLOCAL = &FramePoint{Type: CurrentRowType} } yyVAL.union = yyLOCAL - case 1081: + case 1084: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5596 +//line sql.y:5613 { yyLOCAL = &FramePoint{Type: UnboundedPrecedingType} } yyVAL.union = yyLOCAL - case 1082: + case 1085: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5600 +//line sql.y:5617 { yyLOCAL = &FramePoint{Type: UnboundedFollowingType} } yyVAL.union = yyLOCAL - case 1083: + case 1086: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5604 +//line sql.y:5621 { yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1084: + case 1087: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5608 +//line sql.y:5625 { yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1085: + case 1088: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5612 +//line sql.y:5629 { yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1086: + case 1089: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:5616 +//line sql.y:5633 { yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1087: + case 1090: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5621 +//line sql.y:5638 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1088: + case 1091: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5625 +//line sql.y:5642 { yyLOCAL = yyDollar[1].frameClauseUnion() } yyVAL.union = yyLOCAL - case 1089: + case 1092: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5631 +//line sql.y:5648 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[2].framePointUnion()} } yyVAL.union = yyLOCAL - case 1090: + case 1093: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:5635 +//line sql.y:5652 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[3].framePointUnion(), End: yyDollar[5].framePointUnion()} } yyVAL.union = yyLOCAL - case 1091: + case 1094: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:5640 +//line sql.y:5657 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1092: + case 1095: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Exprs -//line sql.y:5644 +//line sql.y:5661 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 1093: + case 1096: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5649 +//line sql.y:5666 { yyVAL.identifierCI = IdentifierCI{} } - case 1094: + case 1097: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5653 +//line sql.y:5670 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1095: + case 1098: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *WindowSpecification -//line sql.y:5659 +//line sql.y:5676 { yyLOCAL = &WindowSpecification{Name: yyDollar[1].identifierCI, PartitionClause: yyDollar[2].exprsUnion(), OrderClause: yyDollar[3].orderByUnion(), FrameClause: yyDollar[4].frameClauseUnion()} } yyVAL.union = yyLOCAL - case 1096: + case 1099: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5665 +//line sql.y:5682 { yyLOCAL = &OverClause{WindowSpec: yyDollar[3].windowSpecificationUnion()} } yyVAL.union = yyLOCAL - case 1097: + case 1100: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5669 +//line sql.y:5686 { yyLOCAL = &OverClause{WindowName: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 1098: + case 1101: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5675 +//line sql.y:5692 { yyLOCAL = yyDollar[1].overClauseUnion() } yyVAL.union = yyLOCAL - case 1099: + case 1102: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *OverClause -//line sql.y:5679 +//line sql.y:5696 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1100: + case 1103: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:5684 +//line sql.y:5701 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1102: + case 1105: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:5691 +//line sql.y:5708 { yyLOCAL = &NullTreatmentClause{yyDollar[1].nullTreatmentTypeUnion()} } yyVAL.union = yyLOCAL - case 1103: + case 1106: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:5697 +//line sql.y:5714 { yyLOCAL = RespectNullsType } yyVAL.union = yyLOCAL - case 1104: + case 1107: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:5701 +//line sql.y:5718 { yyLOCAL = IgnoreNullsType } yyVAL.union = yyLOCAL - case 1105: + case 1108: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:5707 +//line sql.y:5724 { yyLOCAL = FirstValueExprType } yyVAL.union = yyLOCAL - case 1106: + case 1109: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:5711 +//line sql.y:5728 { yyLOCAL = LastValueExprType } yyVAL.union = yyLOCAL - case 1107: + case 1110: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:5717 +//line sql.y:5734 { yyLOCAL = FromFirstType } yyVAL.union = yyLOCAL - case 1108: + case 1111: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:5721 +//line sql.y:5738 { yyLOCAL = FromLastType } yyVAL.union = yyLOCAL - case 1109: + case 1112: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:5726 +//line sql.y:5743 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1111: + case 1114: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:5733 +//line sql.y:5750 { yyLOCAL = &FromFirstLastClause{yyDollar[1].fromFirstLastTypeUnion()} } yyVAL.union = yyLOCAL - case 1112: + case 1115: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:5739 +//line sql.y:5756 { yyLOCAL = LagExprType } yyVAL.union = yyLOCAL - case 1113: + case 1116: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:5743 +//line sql.y:5760 { yyLOCAL = LeadExprType } yyVAL.union = yyLOCAL - case 1114: + case 1117: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *WindowDefinition -//line sql.y:5749 +//line sql.y:5766 { yyLOCAL = &WindowDefinition{Name: yyDollar[1].identifierCI, WindowSpec: yyDollar[4].windowSpecificationUnion()} } yyVAL.union = yyLOCAL - case 1115: + case 1118: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL WindowDefinitions -//line sql.y:5755 +//line sql.y:5772 { yyLOCAL = WindowDefinitions{yyDollar[1].windowDefinitionUnion()} } yyVAL.union = yyLOCAL - case 1116: + case 1119: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5759 +//line sql.y:5776 { yySLICE := (*WindowDefinitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].windowDefinitionUnion()) } - case 1117: + case 1120: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5765 +//line sql.y:5782 { yyVAL.str = "" } - case 1118: + case 1121: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5769 +//line sql.y:5786 { yyVAL.str = string(yyDollar[2].identifierCI.String()) } - case 1119: + case 1122: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:5775 +//line sql.y:5792 { yyLOCAL = BoolVal(true) } yyVAL.union = yyLOCAL - case 1120: + case 1123: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:5779 +//line sql.y:5796 { yyLOCAL = BoolVal(false) } yyVAL.union = yyLOCAL - case 1121: + case 1124: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5786 +//line sql.y:5803 { yyLOCAL = IsTrueOp } yyVAL.union = yyLOCAL - case 1122: + case 1125: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5790 +//line sql.y:5807 { yyLOCAL = IsNotTrueOp } yyVAL.union = yyLOCAL - case 1123: + case 1126: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5794 +//line sql.y:5811 { yyLOCAL = IsFalseOp } yyVAL.union = yyLOCAL - case 1124: + case 1127: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:5798 +//line sql.y:5815 { yyLOCAL = IsNotFalseOp } yyVAL.union = yyLOCAL - case 1125: + case 1128: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL ComparisonExprOperator +//line sql.y:5821 + { + yyLOCAL = yyDollar[1].comparisonExprOperatorUnion() + } + yyVAL.union = yyLOCAL + case 1129: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL ComparisonExprOperator +//line sql.y:5825 + { + yyLOCAL = NullSafeEqualOp + } + yyVAL.union = yyLOCAL + case 1130: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5804 +//line sql.y:5831 { yyLOCAL = EqualOp } yyVAL.union = yyLOCAL - case 1126: + case 1131: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5808 +//line sql.y:5835 { yyLOCAL = LessThanOp } yyVAL.union = yyLOCAL - case 1127: + case 1132: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5812 +//line sql.y:5839 { yyLOCAL = GreaterThanOp } yyVAL.union = yyLOCAL - case 1128: + case 1133: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5816 +//line sql.y:5843 { yyLOCAL = LessEqualOp } yyVAL.union = yyLOCAL - case 1129: + case 1134: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5820 +//line sql.y:5847 { yyLOCAL = GreaterEqualOp } yyVAL.union = yyLOCAL - case 1130: + case 1135: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:5824 +//line sql.y:5851 { yyLOCAL = NotEqualOp } yyVAL.union = yyLOCAL - case 1131: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL ComparisonExprOperator -//line sql.y:5828 - { - yyLOCAL = NullSafeEqualOp - } - yyVAL.union = yyLOCAL - case 1132: + case 1136: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:5834 +//line sql.y:5857 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 1133: + case 1137: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:5838 +//line sql.y:5861 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 1134: + case 1138: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:5842 +//line sql.y:5865 { yyLOCAL = ListArg(yyDollar[1].str[2:]) markBindVariable(yylex, yyDollar[1].str[2:]) } yyVAL.union = yyLOCAL - case 1135: + case 1139: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Subquery -//line sql.y:5849 +//line sql.y:5872 { yyLOCAL = &Subquery{yyDollar[1].selStmtUnion()} } yyVAL.union = yyLOCAL - case 1136: + case 1140: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:5855 +//line sql.y:5878 { yyLOCAL = Exprs{yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1137: + case 1141: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5859 +//line sql.y:5882 { yySLICE := (*Exprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].exprUnion()) } - case 1138: + case 1142: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5869 +//line sql.y:5892 { yyLOCAL = &FuncExpr{Name: yyDollar[1].identifierCI, Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1139: + case 1143: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5873 +//line sql.y:5896 { yyLOCAL = &FuncExpr{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCI, Exprs: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1140: + case 1144: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5883 +//line sql.y:5906 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("left"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1141: + case 1145: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5887 +//line sql.y:5910 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("right"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1142: + case 1146: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:5891 +//line sql.y:5914 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1143: + case 1147: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:5895 +//line sql.y:5918 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1144: + case 1148: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5899 +//line sql.y:5922 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1145: + case 1149: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:5903 +//line sql.y:5926 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1146: + case 1150: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5907 +//line sql.y:5930 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1147: + case 1151: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5911 +//line sql.y:5934 { yyLOCAL = &CaseExpr{Expr: yyDollar[2].exprUnion(), Whens: yyDollar[3].whensUnion(), Else: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1148: + case 1152: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5915 +//line sql.y:5938 { yyLOCAL = &ValuesFuncExpr{Name: yyDollar[3].colNameUnion()} } yyVAL.union = yyLOCAL - case 1149: + case 1153: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:5919 +//line sql.y:5942 { yyLOCAL = &InsertExpr{Str: yyDollar[3].exprUnion(), Pos: yyDollar[5].exprUnion(), Len: yyDollar[7].exprUnion(), NewStr: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1150: + case 1154: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5923 +//line sql.y:5946 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1151: + case 1155: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5934 +//line sql.y:5957 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("utc_date")} } yyVAL.union = yyLOCAL - case 1152: + case 1156: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5938 +//line sql.y:5961 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1153: + case 1157: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5944 +//line sql.y:5967 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("current_date")} } yyVAL.union = yyLOCAL - case 1154: + case 1158: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5948 +//line sql.y:5971 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("curdate")} } yyVAL.union = yyLOCAL - case 1155: + case 1159: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5952 +//line sql.y:5975 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("utc_time"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1156: + case 1160: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5957 +//line sql.y:5980 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("curtime"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1157: + case 1161: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5962 +//line sql.y:5985 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("current_time"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1158: + case 1162: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5966 +//line sql.y:5989 { yyLOCAL = &CountStar{OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1159: + case 1163: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5970 +//line sql.y:5993 { yyLOCAL = &Count{Distinct: yyDollar[3].booleanUnion(), Args: yyDollar[4].exprsUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1160: + case 1164: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5974 +//line sql.y:5997 { yyLOCAL = &Max{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1161: + case 1165: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5978 +//line sql.y:6001 { yyLOCAL = &Min{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1162: + case 1166: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5982 +//line sql.y:6005 { yyLOCAL = &Sum{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1163: + case 1167: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5986 +//line sql.y:6009 { yyLOCAL = &Avg{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1164: + case 1168: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5990 +//line sql.y:6013 { yyLOCAL = &BitAnd{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1165: + case 1169: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5994 +//line sql.y:6017 { yyLOCAL = &BitOr{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1166: + case 1170: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5998 +//line sql.y:6021 { yyLOCAL = &BitXor{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1167: + case 1171: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6002 +//line sql.y:6025 { yyLOCAL = &Std{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1168: + case 1172: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6006 +//line sql.y:6029 { yyLOCAL = &StdDev{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1169: + case 1173: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6010 +//line sql.y:6033 { yyLOCAL = &StdPop{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1170: + case 1174: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6014 +//line sql.y:6037 { yyLOCAL = &StdSamp{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1171: + case 1175: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6018 +//line sql.y:6041 { yyLOCAL = &VarPop{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1172: + case 1176: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6022 +//line sql.y:6045 { yyLOCAL = &VarSamp{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1173: + case 1177: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6026 +//line sql.y:6049 { yyLOCAL = &Variance{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1174: + case 1178: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6030 +//line sql.y:6053 { yyLOCAL = &GroupConcatExpr{Distinct: yyDollar[3].booleanUnion(), Exprs: yyDollar[4].exprsUnion(), OrderBy: yyDollar[5].orderByUnion(), Separator: yyDollar[6].str, Limit: yyDollar[7].limitUnion()} } yyVAL.union = yyLOCAL - case 1175: + case 1179: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6034 +//line sql.y:6057 { yyLOCAL = &AnyValue{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1176: + case 1180: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6038 +//line sql.y:6061 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprTimestampadd, Date: yyDollar[7].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1177: + case 1181: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6042 +//line sql.y:6065 { yyLOCAL = &TimestampDiffExpr{Unit: yyDollar[3].intervalTypeUnion(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1178: + case 1182: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6046 +//line sql.y:6069 { yyLOCAL = &ExtractFuncExpr{IntervalType: yyDollar[3].intervalTypeUnion(), Expr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1179: + case 1183: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6050 +//line sql.y:6073 { yyLOCAL = &WeightStringFuncExpr{Expr: yyDollar[3].exprUnion(), As: yyDollar[4].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1180: + case 1184: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6054 +//line sql.y:6077 { yyLOCAL = &JSONPrettyExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1181: + case 1185: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6058 +//line sql.y:6081 { yyLOCAL = &JSONStorageFreeExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1182: + case 1186: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6062 +//line sql.y:6085 { yyLOCAL = &JSONStorageSizeExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1183: + case 1187: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6066 +//line sql.y:6089 { yyLOCAL = &TrimFuncExpr{TrimFuncType: LTrimType, Type: LeadingTrimType, StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1184: + case 1188: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6070 +//line sql.y:6093 { yyLOCAL = &TrimFuncExpr{TrimFuncType: RTrimType, Type: TrailingTrimType, StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1185: + case 1189: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:6074 +//line sql.y:6097 { yyLOCAL = &TrimFuncExpr{Type: yyDollar[3].trimTypeUnion(), TrimArg: yyDollar[4].exprUnion(), StringArg: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1186: + case 1190: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6078 +//line sql.y:6101 { yyLOCAL = &TrimFuncExpr{StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1187: + case 1191: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6082 +//line sql.y:6105 { yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1188: + case 1192: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6086 +//line sql.y:6109 { yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion(), Charset: yyDollar[5].str} } yyVAL.union = yyLOCAL - case 1189: + case 1193: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6090 +//line sql.y:6113 { yyLOCAL = &TrimFuncExpr{TrimArg: yyDollar[3].exprUnion(), StringArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1190: + case 1194: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6094 +//line sql.y:6117 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1191: + case 1195: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6098 +//line sql.y:6121 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion(), Pos: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1192: + case 1196: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6102 +//line sql.y:6125 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1193: + case 1197: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6106 +//line sql.y:6129 { yyLOCAL = &LockingFunc{Type: GetLock, Name: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1194: + case 1198: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6110 +//line sql.y:6133 { yyLOCAL = &LockingFunc{Type: IsFreeLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1195: + case 1199: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6114 +//line sql.y:6137 { yyLOCAL = &LockingFunc{Type: IsUsedLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1196: + case 1200: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:6118 +//line sql.y:6141 { yyLOCAL = &LockingFunc{Type: ReleaseAllLocks} } yyVAL.union = yyLOCAL - case 1197: + case 1201: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6122 +//line sql.y:6145 { yyLOCAL = &LockingFunc{Type: ReleaseLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1198: + case 1202: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6126 +//line sql.y:6149 { yyLOCAL = &JSONSchemaValidFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1199: + case 1203: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6130 +//line sql.y:6153 { yyLOCAL = &JSONSchemaValidationReportFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1200: + case 1204: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6134 +//line sql.y:6157 { yyLOCAL = &JSONArrayExpr{Params: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1201: + case 1205: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6138 +//line sql.y:6161 { yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1202: + case 1206: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6142 +//line sql.y:6165 { yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1203: + case 1207: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6146 +//line sql.y:6169 { yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1204: + case 1208: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6150 +//line sql.y:6173 { yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1205: + case 1209: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6154 +//line sql.y:6177 { yyLOCAL = &GeomPropertyFuncExpr{Property: IsEmpty, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1206: + case 1210: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6158 +//line sql.y:6181 { yyLOCAL = &GeomPropertyFuncExpr{Property: IsSimple, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1207: + case 1211: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6162 +//line sql.y:6185 { yyLOCAL = &GeomPropertyFuncExpr{Property: Dimension, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1208: + case 1212: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6166 +//line sql.y:6189 { yyLOCAL = &GeomPropertyFuncExpr{Property: Envelope, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1209: + case 1213: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6170 +//line sql.y:6193 { yyLOCAL = &GeomPropertyFuncExpr{Property: GeometryType, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1210: + case 1214: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6174 +//line sql.y:6197 { yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1211: + case 1215: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6178 +//line sql.y:6201 { yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1212: + case 1216: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6182 +//line sql.y:6205 { yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1213: + case 1217: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6186 +//line sql.y:6209 { yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1214: + case 1218: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6190 +//line sql.y:6213 { yyLOCAL = &LinestrPropertyFuncExpr{Property: EndPoint, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1215: + case 1219: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6194 +//line sql.y:6217 { yyLOCAL = &LinestrPropertyFuncExpr{Property: IsClosed, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1216: + case 1220: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6198 +//line sql.y:6221 { yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1217: + case 1221: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6202 +//line sql.y:6225 { yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1218: + case 1222: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6206 +//line sql.y:6229 { yyLOCAL = &LinestrPropertyFuncExpr{Property: NumPoints, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1219: + case 1223: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6210 +//line sql.y:6233 { yyLOCAL = &LinestrPropertyFuncExpr{Property: PointN, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1220: + case 1224: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6214 +//line sql.y:6237 { yyLOCAL = &LinestrPropertyFuncExpr{Property: StartPoint, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1221: + case 1225: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6218 +//line sql.y:6241 { yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1222: + case 1226: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6222 +//line sql.y:6245 { yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1223: + case 1227: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6226 +//line sql.y:6249 { yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1224: + case 1228: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6230 +//line sql.y:6253 { yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1225: + case 1229: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6234 +//line sql.y:6257 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1226: + case 1230: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6238 +//line sql.y:6261 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1227: + case 1231: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6242 +//line sql.y:6265 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1228: + case 1232: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6246 +//line sql.y:6269 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1229: + case 1233: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6250 +//line sql.y:6273 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1230: + case 1234: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6254 +//line sql.y:6277 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1231: + case 1235: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6258 +//line sql.y:6281 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1232: + case 1236: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6262 +//line sql.y:6285 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1233: + case 1237: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6266 +//line sql.y:6289 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1234: + case 1238: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6270 +//line sql.y:6293 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1235: + case 1239: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6274 +//line sql.y:6297 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1236: + case 1240: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6278 +//line sql.y:6301 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1237: + case 1241: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6282 +//line sql.y:6305 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1238: + case 1242: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6286 +//line sql.y:6309 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1239: + case 1243: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6290 +//line sql.y:6313 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1240: + case 1244: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6294 +//line sql.y:6317 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1241: + case 1245: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6298 +//line sql.y:6321 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1242: + case 1246: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6302 +//line sql.y:6325 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1243: + case 1247: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6306 +//line sql.y:6329 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1244: + case 1248: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6310 +//line sql.y:6333 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1245: + case 1249: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6314 +//line sql.y:6337 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1246: + case 1250: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6318 +//line sql.y:6341 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1247: + case 1251: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6322 +//line sql.y:6345 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1248: + case 1252: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6326 +//line sql.y:6349 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1249: + case 1253: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6330 +//line sql.y:6353 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1250: + case 1254: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6334 +//line sql.y:6357 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1251: + case 1255: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6338 +//line sql.y:6361 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1252: + case 1256: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6342 +//line sql.y:6365 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1253: + case 1257: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6346 +//line sql.y:6369 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1254: + case 1258: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6350 +//line sql.y:6373 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1255: + case 1259: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6354 +//line sql.y:6377 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1256: + case 1260: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6358 +//line sql.y:6381 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1257: + case 1261: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6362 +//line sql.y:6385 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1258: + case 1262: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6366 +//line sql.y:6389 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1259: + case 1263: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6370 +//line sql.y:6393 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1260: + case 1264: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6374 +//line sql.y:6397 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1261: + case 1265: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6378 +//line sql.y:6401 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1262: + case 1266: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6382 +//line sql.y:6405 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1263: + case 1267: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6386 +//line sql.y:6409 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1264: + case 1268: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6390 +//line sql.y:6413 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1265: + case 1269: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6394 +//line sql.y:6417 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1266: + case 1270: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6398 +//line sql.y:6421 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1267: + case 1271: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6402 +//line sql.y:6425 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1268: + case 1272: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6406 +//line sql.y:6429 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1269: + case 1273: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6410 +//line sql.y:6433 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1270: + case 1274: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6414 +//line sql.y:6437 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1271: + case 1275: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6418 +//line sql.y:6441 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1272: + case 1276: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6422 +//line sql.y:6445 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1273: + case 1277: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6426 +//line sql.y:6449 { yyLOCAL = &PolygonPropertyFuncExpr{Property: Area, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1274: + case 1278: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6430 +//line sql.y:6453 { yyLOCAL = &PolygonPropertyFuncExpr{Property: Centroid, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1275: + case 1279: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6434 +//line sql.y:6457 { yyLOCAL = &PolygonPropertyFuncExpr{Property: ExteriorRing, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1276: + case 1280: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6438 +//line sql.y:6461 { yyLOCAL = &PolygonPropertyFuncExpr{Property: InteriorRingN, Polygon: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1277: + case 1281: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6442 +//line sql.y:6465 { yyLOCAL = &PolygonPropertyFuncExpr{Property: NumInteriorRings, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1278: + case 1282: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6446 +//line sql.y:6469 { yyLOCAL = &GeomCollPropertyFuncExpr{Property: GeometryN, GeomColl: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1279: + case 1283: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6450 +//line sql.y:6473 { yyLOCAL = &GeomCollPropertyFuncExpr{Property: NumGeometries, GeomColl: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1280: + case 1284: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6454 +//line sql.y:6477 { yyLOCAL = &GeoHashFromLatLongExpr{Longitude: yyDollar[3].exprUnion(), Latitude: yyDollar[5].exprUnion(), MaxLength: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1281: + case 1285: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6458 +//line sql.y:6481 { yyLOCAL = &GeoHashFromPointExpr{Point: yyDollar[3].exprUnion(), MaxLength: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1282: + case 1286: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6462 +//line sql.y:6485 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: LatitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1283: + case 1287: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6466 +//line sql.y:6489 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: LongitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1284: + case 1288: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6470 +//line sql.y:6493 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: PointFromHash, GeoHash: yyDollar[3].exprUnion(), SridOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1285: + case 1289: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6474 +//line sql.y:6497 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1286: + case 1290: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6478 +//line sql.y:6501 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1287: + case 1291: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6482 +//line sql.y:6505 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion(), Srid: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1288: + case 1292: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6486 +//line sql.y:6509 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1289: + case 1293: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6490 +//line sql.y:6513 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1290: + case 1294: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6494 +//line sql.y:6517 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion(), Bitmask: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1291: + case 1295: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6498 +//line sql.y:6521 { yyLOCAL = &JSONObjectExpr{Params: yyDollar[3].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1292: + case 1296: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6502 +//line sql.y:6525 { yyLOCAL = &JSONQuoteExpr{StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1293: + case 1297: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6506 +//line sql.y:6529 { yyLOCAL = &JSONContainsExpr{Target: yyDollar[3].exprUnion(), Candidate: yyDollar[5].exprsUnion()[0], PathList: yyDollar[5].exprsUnion()[1:]} } yyVAL.union = yyLOCAL - case 1294: + case 1298: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6510 +//line sql.y:6533 { yyLOCAL = &JSONContainsPathExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), PathList: yyDollar[7].exprsUnion()} } yyVAL.union = yyLOCAL - case 1295: + case 1299: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6514 +//line sql.y:6537 { yyLOCAL = &JSONExtractExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1296: + case 1300: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6518 +//line sql.y:6541 { yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1297: + case 1301: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6522 +//line sql.y:6545 { yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1298: + case 1302: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6526 +//line sql.y:6549 { yyLOCAL = &JSONOverlapsExpr{JSONDoc1: yyDollar[3].exprUnion(), JSONDoc2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1299: + case 1303: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6530 +//line sql.y:6553 { yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1300: + case 1304: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6534 +//line sql.y:6557 { yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion(), EscapeChar: yyDollar[9].exprsUnion()[0], PathList: yyDollar[9].exprsUnion()[1:]} } yyVAL.union = yyLOCAL - case 1301: + case 1305: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:6538 +//line sql.y:6561 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1302: + case 1306: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6542 +//line sql.y:6565 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion()} } yyVAL.union = yyLOCAL - case 1303: + case 1307: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6546 +//line sql.y:6569 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), ErrorOnResponse: yyDollar[7].jtOnResponseUnion()} } yyVAL.union = yyLOCAL - case 1304: + case 1308: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:6550 +//line sql.y:6573 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion(), ErrorOnResponse: yyDollar[8].jtOnResponseUnion()} } yyVAL.union = yyLOCAL - case 1305: + case 1309: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6554 +//line sql.y:6577 { yyLOCAL = &JSONAttributesExpr{Type: DepthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1306: + case 1310: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6558 +//line sql.y:6581 { yyLOCAL = &JSONAttributesExpr{Type: ValidAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1307: + case 1311: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6562 +//line sql.y:6585 { yyLOCAL = &JSONAttributesExpr{Type: TypeAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1308: + case 1312: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6566 +//line sql.y:6589 { yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1309: + case 1313: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6570 +//line sql.y:6593 { yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1310: + case 1314: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6574 +//line sql.y:6597 { yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayAppendType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1311: + case 1315: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6578 +//line sql.y:6601 { yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1312: + case 1316: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6582 +//line sql.y:6605 { yyLOCAL = &JSONValueModifierExpr{Type: JSONInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1313: + case 1317: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6586 +//line sql.y:6609 { yyLOCAL = &JSONValueModifierExpr{Type: JSONReplaceType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1314: + case 1318: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6590 +//line sql.y:6613 { yyLOCAL = &JSONValueModifierExpr{Type: JSONSetType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1315: + case 1319: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6594 +//line sql.y:6617 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergeType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1316: + case 1320: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6598 +//line sql.y:6621 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePatchType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1317: + case 1321: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6602 +//line sql.y:6625 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePreserveType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1318: + case 1322: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6606 +//line sql.y:6629 { yyLOCAL = &JSONRemoveExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1319: + case 1323: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6610 +//line sql.y:6633 { yyLOCAL = &JSONUnquoteExpr{JSONValue: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1320: + case 1324: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6614 +//line sql.y:6637 { yyLOCAL = &MultiPolygonExpr{PolygonParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1321: + case 1325: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6618 +//line sql.y:6641 { yyLOCAL = &MultiPointExpr{PointParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1322: + case 1326: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6622 +//line sql.y:6645 { yyLOCAL = &MultiLinestringExpr{LinestringParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1323: + case 1327: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6626 +//line sql.y:6649 { yyLOCAL = &PolygonExpr{LinestringParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1324: + case 1328: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6630 +//line sql.y:6653 { yyLOCAL = &LineStringExpr{PointParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1325: + case 1329: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6634 +//line sql.y:6657 { yyLOCAL = &PointExpr{XCordinate: yyDollar[3].exprUnion(), YCordinate: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1326: + case 1330: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6638 +//line sql.y:6661 { yyLOCAL = &ArgumentLessWindowExpr{Type: yyDollar[1].argumentLessWindowExprTypeUnion(), OverClause: yyDollar[4].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1327: + case 1331: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6642 +//line sql.y:6665 { yyLOCAL = &FirstOrLastValueExpr{Type: yyDollar[1].firstOrLastValueExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1328: + case 1332: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6646 +//line sql.y:6669 { yyLOCAL = &NtileExpr{N: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1329: + case 1333: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:6650 +//line sql.y:6673 { yyLOCAL = &NTHValueExpr{Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), FromFirstLastClause: yyDollar[7].fromFirstLastClauseUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1330: + case 1334: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6654 +//line sql.y:6677 { yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1331: + case 1335: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:6658 +//line sql.y:6681 { yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), Default: yyDollar[6].exprUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1332: + case 1336: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6662 +//line sql.y:6685 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1333: + case 1337: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6666 +//line sql.y:6689 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } yyVAL.union = yyLOCAL - case 1334: + case 1338: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6670 +//line sql.y:6693 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateAdd, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1335: + case 1339: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6674 +//line sql.y:6697 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateSub, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1336: + case 1340: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6678 +//line sql.y:6701 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1337: + case 1341: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6682 +//line sql.y:6705 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } yyVAL.union = yyLOCAL - case 1342: + case 1346: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6692 +//line sql.y:6715 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1343: + case 1347: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6696 +//line sql.y:6719 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1344: + case 1348: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6700 +//line sql.y:6723 { yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL - case 1345: + case 1349: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6704 +//line sql.y:6727 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 1346: + case 1350: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:6709 +//line sql.y:6732 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1347: + case 1351: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6713 +//line sql.y:6736 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1348: + case 1352: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6719 +//line sql.y:6742 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1349: + case 1353: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6723 +//line sql.y:6746 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1350: + case 1354: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6727 +//line sql.y:6750 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1351: + case 1355: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6731 +//line sql.y:6754 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), ReturnOption: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1352: + case 1356: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:6735 +//line sql.y:6758 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), ReturnOption: yyDollar[11].exprUnion(), MatchType: yyDollar[13].exprUnion()} } yyVAL.union = yyLOCAL - case 1353: + case 1357: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6740 +//line sql.y:6763 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1354: + case 1358: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6744 +//line sql.y:6767 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), MatchType: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1355: + case 1359: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6748 +//line sql.y:6771 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1356: + case 1360: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6752 +//line sql.y:6775 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1357: + case 1361: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6756 +//line sql.y:6779 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion(), Occurrence: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1358: + case 1362: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:6760 +//line sql.y:6783 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion(), Occurrence: yyDollar[11].exprUnion(), MatchType: yyDollar[13].exprUnion()} } yyVAL.union = yyLOCAL - case 1359: + case 1363: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6765 +//line sql.y:6788 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1360: + case 1364: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6769 +//line sql.y:6792 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1361: + case 1365: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6773 +//line sql.y:6796 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1362: + case 1366: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:6777 +//line sql.y:6800 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), MatchType: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1363: + case 1367: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6784 +//line sql.y:6807 { yyLOCAL = &ExtractValueExpr{Fragment: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1364: + case 1368: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6788 +//line sql.y:6811 { yyLOCAL = &UpdateXMLExpr{Target: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion(), NewXML: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1365: + case 1369: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6794 +//line sql.y:6817 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatBytesType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1366: + case 1370: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6798 +//line sql.y:6821 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatPicoTimeType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1367: + case 1371: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:6802 +//line sql.y:6825 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsCurrentThreadIDType} } yyVAL.union = yyLOCAL - case 1368: + case 1372: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6806 +//line sql.y:6829 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsThreadIDType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1369: + case 1373: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6812 +//line sql.y:6835 { yyLOCAL = >IDFuncExpr{Type: GTIDSubsetType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1370: + case 1374: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6816 +//line sql.y:6839 { yyLOCAL = >IDFuncExpr{Type: GTIDSubtractType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1371: + case 1375: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6820 +//line sql.y:6843 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1372: + case 1376: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6824 +//line sql.y:6847 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1373: + case 1377: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6828 +//line sql.y:6851 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1374: + case 1378: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6832 +//line sql.y:6855 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1375: + case 1379: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6836 +//line sql.y:6859 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion(), Channel: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1376: + case 1380: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:6841 +//line sql.y:6864 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1377: + case 1381: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:6845 +//line sql.y:6868 { yyLOCAL = yyDollar[2].convertTypeUnion() } yyVAL.union = yyLOCAL - case 1378: + case 1382: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6851 +//line sql.y:6874 { yyLOCAL = IntervalDayHour } yyVAL.union = yyLOCAL - case 1379: + case 1383: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6855 +//line sql.y:6878 { yyLOCAL = IntervalDayMicrosecond } yyVAL.union = yyLOCAL - case 1380: + case 1384: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6859 +//line sql.y:6882 { yyLOCAL = IntervalDayMinute } yyVAL.union = yyLOCAL - case 1381: + case 1385: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6863 +//line sql.y:6886 { yyLOCAL = IntervalDaySecond } yyVAL.union = yyLOCAL - case 1382: + case 1386: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6867 +//line sql.y:6890 { yyLOCAL = IntervalHourMicrosecond } yyVAL.union = yyLOCAL - case 1383: + case 1387: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6871 +//line sql.y:6894 { yyLOCAL = IntervalHourMinute } yyVAL.union = yyLOCAL - case 1384: + case 1388: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6875 +//line sql.y:6898 { yyLOCAL = IntervalHourSecond } yyVAL.union = yyLOCAL - case 1385: + case 1389: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6879 +//line sql.y:6902 { yyLOCAL = IntervalMinuteMicrosecond } yyVAL.union = yyLOCAL - case 1386: + case 1390: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6883 +//line sql.y:6906 { yyLOCAL = IntervalMinuteSecond } yyVAL.union = yyLOCAL - case 1387: + case 1391: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6887 +//line sql.y:6910 { yyLOCAL = IntervalSecondMicrosecond } yyVAL.union = yyLOCAL - case 1388: + case 1392: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6891 +//line sql.y:6914 { yyLOCAL = IntervalYearMonth } yyVAL.union = yyLOCAL - case 1389: + case 1393: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6895 +//line sql.y:6918 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1390: + case 1394: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6899 +//line sql.y:6922 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1391: + case 1395: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6903 +//line sql.y:6926 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1392: + case 1396: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6907 +//line sql.y:6930 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1393: + case 1397: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6911 +//line sql.y:6934 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1394: + case 1398: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6915 +//line sql.y:6938 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1395: + case 1399: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6919 +//line sql.y:6942 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1396: + case 1400: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6923 +//line sql.y:6946 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1397: + case 1401: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6927 +//line sql.y:6950 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1398: + case 1402: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6933 +//line sql.y:6956 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1399: + case 1403: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6937 +//line sql.y:6960 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1400: + case 1404: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6941 +//line sql.y:6964 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1401: + case 1405: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6945 +//line sql.y:6968 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1402: + case 1406: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6949 +//line sql.y:6972 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1403: + case 1407: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6953 +//line sql.y:6976 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1404: + case 1408: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6957 +//line sql.y:6980 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1405: + case 1409: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6961 +//line sql.y:6984 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1406: + case 1410: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6965 +//line sql.y:6988 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1407: + case 1411: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6969 +//line sql.y:6992 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1408: + case 1412: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6973 +//line sql.y:6996 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1409: + case 1413: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6977 +//line sql.y:7000 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1410: + case 1414: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6981 +//line sql.y:7004 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1411: + case 1415: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6985 +//line sql.y:7008 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1412: + case 1416: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6989 +//line sql.y:7012 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1413: + case 1417: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6993 +//line sql.y:7016 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1414: + case 1418: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:6997 +//line sql.y:7020 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1415: + case 1419: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7001 +//line sql.y:7024 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1418: + case 1422: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:7011 +//line sql.y:7034 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 1419: + case 1423: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:7015 +//line sql.y:7038 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 1420: + case 1424: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:7019 +//line sql.y:7042 { yyLOCAL = convertStringToInt(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 1421: + case 1425: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7029 +//line sql.y:7052 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("if"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1422: + case 1426: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7033 +//line sql.y:7056 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("database"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1423: + case 1427: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7037 +//line sql.y:7060 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("schema"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1424: + case 1428: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7041 +//line sql.y:7064 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("mod"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1425: + case 1429: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7045 +//line sql.y:7068 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("replace"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1426: + case 1430: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7051 +//line sql.y:7074 { yyLOCAL = NoOption } yyVAL.union = yyLOCAL - case 1427: + case 1431: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7055 +//line sql.y:7078 { yyLOCAL = BooleanModeOpt } yyVAL.union = yyLOCAL - case 1428: + case 1432: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7059 +//line sql.y:7082 { yyLOCAL = NaturalLanguageModeOpt } yyVAL.union = yyLOCAL - case 1429: + case 1433: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7063 +//line sql.y:7086 { yyLOCAL = NaturalLanguageModeWithQueryExpansionOpt } yyVAL.union = yyLOCAL - case 1430: + case 1434: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7067 +//line sql.y:7090 { yyLOCAL = QueryExpansionOpt } yyVAL.union = yyLOCAL - case 1431: + case 1435: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7073 +//line sql.y:7096 { yyVAL.str = string(yyDollar[1].identifierCI.String()) } - case 1432: + case 1436: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7077 +//line sql.y:7100 { yyVAL.str = string(yyDollar[1].str) } - case 1433: + case 1437: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7081 +//line sql.y:7104 { yyVAL.str = string(yyDollar[1].str) } - case 1434: + case 1438: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7087 +//line sql.y:7110 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1435: + case 1439: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7091 +//line sql.y:7114 { yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: ptr.Of(convertStringToInt(yyDollar[4].str))} } yyVAL.union = yyLOCAL - case 1436: + case 1440: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7095 +//line sql.y:7118 { yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: ptr.Of(convertStringToInt(yyDollar[4].str))} } yyVAL.union = yyLOCAL - case 1437: + case 1441: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7101 +//line sql.y:7124 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1438: + case 1442: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7105 +//line sql.y:7128 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} } yyVAL.union = yyLOCAL - case 1439: + case 1443: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7109 +//line sql.y:7132 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1440: + case 1444: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7113 +//line sql.y:7136 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1441: + case 1445: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7117 +//line sql.y:7140 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} yyLOCAL.Length = yyDollar[2].LengthScaleOption.Length yyLOCAL.Scale = yyDollar[2].LengthScaleOption.Scale } yyVAL.union = yyLOCAL - case 1442: + case 1446: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7123 +//line sql.y:7146 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1443: + case 1447: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7127 +//line sql.y:7150 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1444: + case 1448: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7131 +//line sql.y:7154 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1445: + case 1449: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7135 +//line sql.y:7158 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1446: + case 1450: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7139 +//line sql.y:7162 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1447: + case 1451: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7143 +//line sql.y:7166 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1448: + case 1452: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7147 +//line sql.y:7170 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1449: + case 1453: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7151 +//line sql.y:7174 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1450: + case 1454: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7155 +//line sql.y:7178 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1451: + case 1455: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7159 +//line sql.y:7182 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1452: + case 1456: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7165 +//line sql.y:7188 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1453: + case 1457: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:7169 +//line sql.y:7192 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1454: + case 1458: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7174 +//line sql.y:7197 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1455: + case 1459: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7178 +//line sql.y:7201 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1456: + case 1460: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7183 +//line sql.y:7206 { yyVAL.str = string("") } - case 1457: + case 1461: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7187 +//line sql.y:7210 { yyVAL.str = encodeSQLString(yyDollar[2].str) } - case 1458: + case 1462: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*When -//line sql.y:7193 +//line sql.y:7216 { yyLOCAL = []*When{yyDollar[1].whenUnion()} } yyVAL.union = yyLOCAL - case 1459: + case 1463: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7197 +//line sql.y:7220 { yySLICE := (*[]*When)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].whenUnion()) } - case 1460: + case 1464: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *When -//line sql.y:7203 +//line sql.y:7226 { yyLOCAL = &When{Cond: yyDollar[2].exprUnion(), Val: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1461: + case 1465: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7208 +//line sql.y:7231 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1462: + case 1466: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7212 +//line sql.y:7235 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1463: + case 1467: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7218 +//line sql.y:7241 { yyLOCAL = &ColName{Name: yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1464: + case 1468: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7222 +//line sql.y:7245 { yyLOCAL = &ColName{Name: NewIdentifierCI(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL - case 1465: + case 1469: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColName -//line sql.y:7226 +//line sql.y:7249 { yyLOCAL = &ColName{Qualifier: TableName{Name: yyDollar[1].identifierCS}, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 1466: + case 1470: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColName -//line sql.y:7230 +//line sql.y:7253 { yyLOCAL = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}, Name: yyDollar[5].identifierCI} } yyVAL.union = yyLOCAL - case 1467: + case 1471: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7236 +//line sql.y:7259 { yyLOCAL = yyDollar[1].colNameUnion() } yyVAL.union = yyLOCAL - case 1468: + case 1472: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7240 +//line sql.y:7263 { yyLOCAL = &Offset{V: convertStringToInt(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1469: + case 1473: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7246 +//line sql.y:7269 { // TODO(sougou): Deprecate this construct. if yyDollar[1].identifierCI.Lowered() != "value" { @@ -21180,442 +21240,442 @@ yydefault: yyLOCAL = NewIntLiteral("1") } yyVAL.union = yyLOCAL - case 1470: + case 1474: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7255 +//line sql.y:7278 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1471: + case 1475: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7259 +//line sql.y:7282 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 1472: + case 1476: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *GroupBy -//line sql.y:7264 +//line sql.y:7287 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1473: + case 1477: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *GroupBy -//line sql.y:7268 +//line sql.y:7291 { yyLOCAL = &GroupBy{Exprs: yyDollar[3].exprsUnion(), WithRollup: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 1474: + case 1478: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7273 +//line sql.y:7296 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1475: + case 1479: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:7277 +//line sql.y:7300 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1476: + case 1480: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7283 +//line sql.y:7306 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1477: + case 1481: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7287 +//line sql.y:7310 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1478: + case 1482: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *NamedWindow -//line sql.y:7293 +//line sql.y:7316 { yyLOCAL = &NamedWindow{yyDollar[2].windowDefinitionsUnion()} } yyVAL.union = yyLOCAL - case 1479: + case 1483: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7299 +//line sql.y:7322 { yyLOCAL = NamedWindows{yyDollar[1].namedWindowUnion()} } yyVAL.union = yyLOCAL - case 1480: + case 1484: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7303 +//line sql.y:7326 { yySLICE := (*NamedWindows)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].namedWindowUnion()) } - case 1481: + case 1485: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7308 +//line sql.y:7331 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1482: + case 1486: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7312 +//line sql.y:7335 { yyLOCAL = yyDollar[1].namedWindowsUnion() } yyVAL.union = yyLOCAL - case 1483: + case 1487: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7317 +//line sql.y:7340 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1484: + case 1488: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7321 +//line sql.y:7344 { yyLOCAL = yyDollar[1].orderByUnion() } yyVAL.union = yyLOCAL - case 1485: + case 1489: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7327 +//line sql.y:7350 { yyLOCAL = yyDollar[3].orderByUnion() } yyVAL.union = yyLOCAL - case 1486: + case 1490: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7333 +//line sql.y:7356 { yyLOCAL = OrderBy{yyDollar[1].orderUnion()} } yyVAL.union = yyLOCAL - case 1487: + case 1491: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7337 +//line sql.y:7360 { yySLICE := (*OrderBy)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].orderUnion()) } - case 1488: + case 1492: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Order -//line sql.y:7343 +//line sql.y:7366 { yyLOCAL = &Order{Expr: yyDollar[1].exprUnion(), Direction: yyDollar[2].orderDirectionUnion()} } yyVAL.union = yyLOCAL - case 1489: + case 1493: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7348 +//line sql.y:7371 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 1490: + case 1494: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7352 +//line sql.y:7375 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 1491: + case 1495: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7356 +//line sql.y:7379 { yyLOCAL = DescOrder } yyVAL.union = yyLOCAL - case 1492: + case 1496: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Limit -//line sql.y:7361 +//line sql.y:7384 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1493: + case 1497: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Limit -//line sql.y:7365 +//line sql.y:7388 { yyLOCAL = yyDollar[1].limitUnion() } yyVAL.union = yyLOCAL - case 1494: + case 1498: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Limit -//line sql.y:7371 +//line sql.y:7394 { yyLOCAL = &Limit{Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1495: + case 1499: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7375 +//line sql.y:7398 { yyLOCAL = &Limit{Offset: yyDollar[2].exprUnion(), Rowcount: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1496: + case 1500: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7379 +//line sql.y:7402 { yyLOCAL = &Limit{Offset: yyDollar[4].exprUnion(), Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1497: + case 1501: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7384 +//line sql.y:7407 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1498: + case 1502: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7388 +//line sql.y:7411 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1499: + case 1503: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7392 +//line sql.y:7415 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1500: + case 1504: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7396 +//line sql.y:7419 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1501: + case 1505: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7400 +//line sql.y:7423 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1502: + case 1506: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7407 +//line sql.y:7430 { yyLOCAL = &LockOption{Type: DefaultType} } yyVAL.union = yyLOCAL - case 1503: + case 1507: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7411 +//line sql.y:7434 { yyLOCAL = &LockOption{Type: NoneType} } yyVAL.union = yyLOCAL - case 1504: + case 1508: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7415 +//line sql.y:7438 { yyLOCAL = &LockOption{Type: SharedType} } yyVAL.union = yyLOCAL - case 1505: + case 1509: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7419 +//line sql.y:7442 { yyLOCAL = &LockOption{Type: ExclusiveType} } yyVAL.union = yyLOCAL - case 1506: + case 1510: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7425 +//line sql.y:7448 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1507: + case 1511: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7429 +//line sql.y:7452 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1508: + case 1512: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7433 +//line sql.y:7456 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1509: + case 1513: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7437 +//line sql.y:7460 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1510: + case 1514: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7442 +//line sql.y:7465 { yyVAL.str = "" } - case 1511: + case 1515: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7446 +//line sql.y:7469 { yyVAL.str = string(yyDollar[3].str) } - case 1512: + case 1516: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7450 +//line sql.y:7473 { yyVAL.str = string(yyDollar[3].str) } - case 1513: + case 1517: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7454 +//line sql.y:7477 { yyVAL.str = string(yyDollar[3].str) } - case 1514: + case 1518: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7459 +//line sql.y:7482 { yyVAL.str = "" } - case 1515: + case 1519: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7463 +//line sql.y:7486 { yyVAL.str = yyDollar[3].str } - case 1516: + case 1520: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7469 +//line sql.y:7492 { yyVAL.str = string(yyDollar[1].str) } - case 1517: + case 1521: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7473 +//line sql.y:7496 { yyVAL.str = string(yyDollar[1].str) } - case 1518: + case 1522: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7478 +//line sql.y:7501 { yyVAL.str = "" } - case 1519: + case 1523: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:7482 +//line sql.y:7505 { yyVAL.str = yyDollar[2].str } - case 1520: + case 1524: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7487 +//line sql.y:7510 { yyVAL.str = "cascaded" } - case 1521: + case 1525: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7491 +//line sql.y:7514 { yyVAL.str = string(yyDollar[1].str) } - case 1522: + case 1526: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7495 +//line sql.y:7518 { yyVAL.str = string(yyDollar[1].str) } - case 1523: + case 1527: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Definer -//line sql.y:7500 +//line sql.y:7523 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1524: + case 1528: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:7504 +//line sql.y:7527 { yyLOCAL = yyDollar[3].definerUnion() } yyVAL.union = yyLOCAL - case 1525: + case 1529: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Definer -//line sql.y:7510 +//line sql.y:7533 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), } } yyVAL.union = yyLOCAL - case 1526: + case 1530: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:7516 +//line sql.y:7539 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), } } yyVAL.union = yyLOCAL - case 1527: + case 1531: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Definer -//line sql.y:7522 +//line sql.y:7545 { yyLOCAL = &Definer{ Name: yyDollar[1].str, @@ -21623,433 +21683,433 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1528: + case 1532: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7531 +//line sql.y:7554 { yyVAL.str = encodeSQLString(yyDollar[1].str) } - case 1529: + case 1533: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7535 +//line sql.y:7558 { yyVAL.str = formatIdentifier(yyDollar[1].str) } - case 1530: + case 1534: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7540 +//line sql.y:7563 { yyVAL.str = "" } - case 1531: + case 1535: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7544 +//line sql.y:7567 { yyVAL.str = formatAddress(yyDollar[1].str) } - case 1532: + case 1536: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:7550 +//line sql.y:7573 { yyLOCAL = ForUpdateLock } yyVAL.union = yyLOCAL - case 1533: + case 1537: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Lock -//line sql.y:7554 +//line sql.y:7577 { yyLOCAL = ForUpdateLockNoWait } yyVAL.union = yyLOCAL - case 1534: + case 1538: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:7558 +//line sql.y:7581 { yyLOCAL = ForUpdateLockSkipLocked } yyVAL.union = yyLOCAL - case 1535: + case 1539: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:7562 +//line sql.y:7585 { yyLOCAL = ForShareLock } yyVAL.union = yyLOCAL - case 1536: + case 1540: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Lock -//line sql.y:7566 +//line sql.y:7589 { yyLOCAL = ForShareLockNoWait } yyVAL.union = yyLOCAL - case 1537: + case 1541: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:7570 +//line sql.y:7593 { yyLOCAL = ForShareLockSkipLocked } yyVAL.union = yyLOCAL - case 1538: + case 1542: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:7574 +//line sql.y:7597 { yyLOCAL = ShareModeLock } yyVAL.union = yyLOCAL - case 1539: + case 1543: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7580 +//line sql.y:7603 { yyLOCAL = &SelectInto{Type: IntoOutfileS3, FileName: encodeSQLString(yyDollar[4].str), Charset: yyDollar[5].columnCharset, FormatOption: yyDollar[6].str, ExportOption: yyDollar[7].str, Manifest: yyDollar[8].str, Overwrite: yyDollar[9].str} } yyVAL.union = yyLOCAL - case 1540: + case 1544: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7584 +//line sql.y:7607 { yyLOCAL = &SelectInto{Type: IntoDumpfile, FileName: encodeSQLString(yyDollar[3].str), Charset: ColumnCharset{}, FormatOption: "", ExportOption: "", Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1541: + case 1545: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:7588 +//line sql.y:7611 { yyLOCAL = &SelectInto{Type: IntoOutfile, FileName: encodeSQLString(yyDollar[3].str), Charset: yyDollar[4].columnCharset, FormatOption: "", ExportOption: yyDollar[5].str, Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1542: + case 1546: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7593 +//line sql.y:7616 { yyVAL.str = "" } - case 1543: + case 1547: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7597 +//line sql.y:7620 { yyVAL.str = " format csv" + yyDollar[3].str } - case 1544: + case 1548: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7601 +//line sql.y:7624 { yyVAL.str = " format text" + yyDollar[3].str } - case 1545: + case 1549: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7606 +//line sql.y:7629 { yyVAL.str = "" } - case 1546: + case 1550: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7610 +//line sql.y:7633 { yyVAL.str = " header" } - case 1547: + case 1551: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7615 +//line sql.y:7638 { yyVAL.str = "" } - case 1548: + case 1552: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7619 +//line sql.y:7642 { yyVAL.str = " manifest on" } - case 1549: + case 1553: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7623 +//line sql.y:7646 { yyVAL.str = " manifest off" } - case 1550: + case 1554: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7628 +//line sql.y:7651 { yyVAL.str = "" } - case 1551: + case 1555: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7632 +//line sql.y:7655 { yyVAL.str = " overwrite on" } - case 1552: + case 1556: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7636 +//line sql.y:7659 { yyVAL.str = " overwrite off" } - case 1553: + case 1557: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7642 +//line sql.y:7665 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1554: + case 1558: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7647 +//line sql.y:7670 { yyVAL.str = "" } - case 1555: + case 1559: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7651 +//line sql.y:7674 { yyVAL.str = " lines" + yyDollar[2].str } - case 1556: + case 1560: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7657 +//line sql.y:7680 { yyVAL.str = yyDollar[1].str } - case 1557: + case 1561: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7661 +//line sql.y:7684 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1558: + case 1562: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7667 +//line sql.y:7690 { yyVAL.str = " starting by " + encodeSQLString(yyDollar[3].str) } - case 1559: + case 1563: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7671 +//line sql.y:7694 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1560: + case 1564: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7676 +//line sql.y:7699 { yyVAL.str = "" } - case 1561: + case 1565: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7680 +//line sql.y:7703 { yyVAL.str = " " + yyDollar[1].str + yyDollar[2].str } - case 1562: + case 1566: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7686 +//line sql.y:7709 { yyVAL.str = yyDollar[1].str } - case 1563: + case 1567: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7690 +//line sql.y:7713 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1564: + case 1568: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7696 +//line sql.y:7719 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1565: + case 1569: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:7700 +//line sql.y:7723 { yyVAL.str = yyDollar[1].str + " enclosed by " + encodeSQLString(yyDollar[4].str) } - case 1566: + case 1570: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7704 +//line sql.y:7727 { yyVAL.str = " escaped by " + encodeSQLString(yyDollar[3].str) } - case 1567: + case 1571: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7709 +//line sql.y:7732 { yyVAL.str = "" } - case 1568: + case 1572: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7713 +//line sql.y:7736 { yyVAL.str = " optionally" } - case 1569: + case 1573: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Insert -//line sql.y:7726 +//line sql.y:7749 { yyLOCAL = &Insert{Rows: yyDollar[2].valuesUnion(), RowAlias: yyDollar[3].rowAliasUnion()} } yyVAL.union = yyLOCAL - case 1570: + case 1574: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Insert -//line sql.y:7730 +//line sql.y:7753 { yyLOCAL = &Insert{Rows: yyDollar[1].selStmtUnion()} } yyVAL.union = yyLOCAL - case 1571: + case 1575: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *Insert -//line sql.y:7734 +//line sql.y:7757 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[5].valuesUnion(), RowAlias: yyDollar[6].rowAliasUnion()} } yyVAL.union = yyLOCAL - case 1572: + case 1576: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *Insert -//line sql.y:7738 +//line sql.y:7761 { yyLOCAL = &Insert{Columns: []IdentifierCI{}, Rows: yyDollar[4].valuesUnion(), RowAlias: yyDollar[5].rowAliasUnion()} } yyVAL.union = yyLOCAL - case 1573: + case 1577: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:7742 +//line sql.y:7765 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[4].selStmtUnion()} } yyVAL.union = yyLOCAL - case 1574: + case 1578: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:7748 +//line sql.y:7771 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1575: + case 1579: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:7752 +//line sql.y:7775 { yyLOCAL = Columns{yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 1576: + case 1580: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7756 +//line sql.y:7779 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 1577: + case 1581: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:7760 +//line sql.y:7783 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[5].identifierCI) } - case 1578: + case 1582: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:7765 +//line sql.y:7788 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1579: + case 1583: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:7769 +//line sql.y:7792 { yyLOCAL = &RowAlias{TableName: yyDollar[2].identifierCS} } yyVAL.union = yyLOCAL - case 1580: + case 1584: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:7773 +//line sql.y:7796 { yyLOCAL = &RowAlias{TableName: yyDollar[2].identifierCS, Columns: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 1581: + case 1585: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7778 +//line sql.y:7801 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1582: + case 1586: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7782 +//line sql.y:7805 { yyLOCAL = yyDollar[5].updateExprsUnion() } yyVAL.union = yyLOCAL - case 1583: + case 1587: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Values -//line sql.y:7788 +//line sql.y:7811 { yyLOCAL = Values{yyDollar[1].valTupleUnion()} } yyVAL.union = yyLOCAL - case 1584: + case 1588: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7792 +//line sql.y:7815 { yySLICE := (*Values)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) } - case 1585: + case 1589: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7798 +//line sql.y:7821 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 1586: + case 1590: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7802 +//line sql.y:7825 { yyLOCAL = ValTuple{} } yyVAL.union = yyLOCAL - case 1587: + case 1591: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7808 +//line sql.y:7831 { yyLOCAL = ValTuple(yyDollar[2].exprsUnion()) } yyVAL.union = yyLOCAL - case 1588: + case 1592: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL ValTuple -//line sql.y:7812 +//line sql.y:7835 { yyLOCAL = ValTuple(yyDollar[3].exprsUnion()) } yyVAL.union = yyLOCAL - case 1589: + case 1593: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7817 +//line sql.y:7840 { if len(yyDollar[1].valTupleUnion()) == 1 { yyLOCAL = yyDollar[1].valTupleUnion()[0] @@ -22058,300 +22118,300 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1590: + case 1594: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:7827 +//line sql.y:7850 { yyLOCAL = UpdateExprs{yyDollar[1].updateExprUnion()} } yyVAL.union = yyLOCAL - case 1591: + case 1595: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7831 +//line sql.y:7854 { yySLICE := (*UpdateExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].updateExprUnion()) } - case 1592: + case 1596: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *UpdateExpr -//line sql.y:7837 +//line sql.y:7860 { yyLOCAL = &UpdateExpr{Name: yyDollar[1].colNameUnion(), Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1594: + case 1598: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7844 +//line sql.y:7867 { yyVAL.str = "charset" } - case 1597: + case 1601: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7854 +//line sql.y:7877 { yyLOCAL = NewStrLiteral(yyDollar[1].identifierCI.String()) } yyVAL.union = yyLOCAL - case 1598: + case 1602: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7858 +//line sql.y:7881 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1599: + case 1603: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7862 +//line sql.y:7885 { yyLOCAL = &Default{} } yyVAL.union = yyLOCAL - case 1602: + case 1606: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7871 +//line sql.y:7894 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1603: + case 1607: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:7873 +//line sql.y:7896 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1604: + case 1608: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7876 +//line sql.y:7899 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1605: + case 1609: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:7878 +//line sql.y:7901 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1606: + case 1610: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7881 +//line sql.y:7904 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1607: + case 1611: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line sql.y:7883 +//line sql.y:7906 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1608: + case 1612: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Ignore -//line sql.y:7886 +//line sql.y:7909 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1609: + case 1613: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Ignore -//line sql.y:7888 +//line sql.y:7911 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1610: + case 1614: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7891 +//line sql.y:7914 { yyVAL.empty = struct{}{} } - case 1611: + case 1615: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7893 +//line sql.y:7916 { yyVAL.empty = struct{}{} } - case 1612: + case 1616: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7895 +//line sql.y:7918 { yyVAL.empty = struct{}{} } - case 1613: + case 1617: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:7899 +//line sql.y:7922 { yyLOCAL = &CallProc{Name: yyDollar[2].tableName, Params: yyDollar[4].exprsUnion()} } yyVAL.union = yyLOCAL - case 1614: + case 1618: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:7904 +//line sql.y:7927 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1615: + case 1619: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:7908 +//line sql.y:7931 { yyLOCAL = yyDollar[1].exprsUnion() } yyVAL.union = yyLOCAL - case 1616: + case 1620: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:7913 +//line sql.y:7936 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1617: + case 1621: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:7915 +//line sql.y:7938 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } yyVAL.union = yyLOCAL - case 1618: + case 1622: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:7919 +//line sql.y:7942 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), String: string(yyDollar[2].identifierCI.String())} } yyVAL.union = yyLOCAL - case 1619: + case 1623: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7925 +//line sql.y:7948 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1620: + case 1624: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7929 +//line sql.y:7952 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 1622: + case 1626: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7936 +//line sql.y:7959 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 1623: + case 1627: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7942 +//line sql.y:7965 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1624: + case 1628: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7946 +//line sql.y:7969 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1625: + case 1629: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7952 +//line sql.y:7975 { yyVAL.identifierCS = NewIdentifierCS("") } - case 1626: + case 1630: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7956 +//line sql.y:7979 { yyVAL.identifierCS = yyDollar[1].identifierCS } - case 1628: + case 1632: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7963 +//line sql.y:7986 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1629: + case 1633: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:7969 +//line sql.y:7992 { yyLOCAL = &Kill{Type: yyDollar[2].killTypeUnion(), ProcesslistID: convertStringToUInt64(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 1630: + case 1634: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL KillType -//line sql.y:7975 +//line sql.y:7998 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1631: + case 1635: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:7979 +//line sql.y:8002 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1632: + case 1636: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:7983 +//line sql.y:8006 { yyLOCAL = QueryType } yyVAL.union = yyLOCAL - case 2251: + case 2257: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8630 +//line sql.y:8655 { } - case 2252: + case 2258: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8635 +//line sql.y:8660 { } - case 2253: + case 2259: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8639 +//line sql.y:8664 { skipToEnd(yylex) } - case 2254: + case 2260: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8644 +//line sql.y:8669 { skipToEnd(yylex) } - case 2255: + case 2261: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8648 +//line sql.y:8673 { skipToEnd(yylex) } - case 2256: + case 2262: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8652 +//line sql.y:8677 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index 98ac245f4ad..ba6c2a6081b 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -238,11 +238,16 @@ func markBindVariable(yylex yyLexer, bvar string) { // In order to ensure lower precedence of reduction, this rule has to come before the precedence declaration of STRING. // This precedence should not be used anywhere else other than with non-reserved-keywords that are also used for type-casting a STRING. %nonassoc STRING_TYPE_PREFIX_NON_KEYWORD +// ANY_SOME is used to resolve shift-reduce conflicts occurring due to '(' followed by ANY and SOME keywords. Since ANY and SOME are used in +// predicates as column modifiers, shifting on a '(' conflicts with reducing the keywords to a non_reserved_keyword. Since we want shifting to +// take precedence, we add this precedence to the reduction rules. +%nonassoc ANY_SOME %token LEX_ERROR %left UNION %token SELECT STREAM VSTREAM INSERT UPDATE DELETE FROM WHERE GROUP HAVING ORDER BY LIMIT OFFSET FOR -%token ALL DISTINCT AS EXISTS ASC DESC INTO DUPLICATE DEFAULT SET LOCK UNLOCK KEYS DO CALL +%token DISTINCT AS EXISTS ASC DESC INTO DUPLICATE DEFAULT SET LOCK UNLOCK KEYS DO CALL +%left ALL ANY SOME %token DISTINCTROW PARSER GENERATED ALWAYS %token OUTFILE S3 DATA LOAD LINES TERMINATED ESCAPED ENCLOSED %token DUMPFILE CSV HEADER MANIFEST OVERWRITE STARTING OPTIONALLY @@ -495,7 +500,7 @@ func markBindVariable(yylex yyLexer, bvar string) { %type index_hint_list index_hint_list_opt %type where_expression_opt %type boolean_value -%type compare +%type compare any_all_compare %type insert_data %type num_val %type function_call_keyword function_call_nonkeyword function_call_generic function_call_conflict @@ -5282,7 +5287,7 @@ null_or_unknown: bool_pri: bool_pri IS null_or_unknown %prec IS { - $$ = &IsExpr{Left: $1, Right: IsNullOp} + $$ = &IsExpr{Left: $1, Right: IsNullOp} } | bool_pri IS NOT null_or_unknown %prec IS { @@ -5292,6 +5297,18 @@ bool_pri IS null_or_unknown %prec IS { $$ = &ComparisonExpr{Left: $1, Operator: $2, Right: $3} } +| bool_pri any_all_compare ANY subquery + { + $$ = &ComparisonExpr{Left: $1, Operator: $2, Modifier: Any, Right: $4 } + } +| bool_pri any_all_compare SOME subquery + { + $$ = &ComparisonExpr{Left: $1, Operator: $2, Modifier: Any, Right: $4 } + } +| bool_pri any_all_compare ALL subquery + { + $$ = &ComparisonExpr{Left: $1, Operator: $2, Modifier: All, Right: $4 } + } | predicate %prec EXPRESSION_PREC_SETTER { $$ = $1 @@ -5800,6 +5817,16 @@ is_suffix: } compare: + any_all_compare %prec ANY_SOME + { + $$ = $1 + } +| NULL_SAFE_EQUAL + { + $$ = NullSafeEqualOp + } + +any_all_compare: '=' { $$ = EqualOp @@ -5824,10 +5851,6 @@ compare: { $$ = NotEqualOp } -| NULL_SAFE_EQUAL - { - $$ = NullSafeEqualOp - } col_tuple: row_tuple @@ -8162,6 +8185,7 @@ non_reserved_keyword: | AFTER | ALGORITHM | ALWAYS +| ANY %prec ANY_SOME | ANY_VALUE %prec FUNCTION_CALL_NON_KEYWORD | ARRAY | ASCII @@ -8460,6 +8484,7 @@ non_reserved_keyword: | SLOW | SMALLINT | SNAPSHOT +| SOME %prec ANY_SOME | SQL | SQL_TSI_DAY | SQL_TSI_HOUR diff --git a/go/vt/sqlparser/testdata/select_cases.txt b/go/vt/sqlparser/testdata/select_cases.txt index 835a4ad4931..3edec6dae7e 100644 --- a/go/vt/sqlparser/testdata/select_cases.txt +++ b/go/vt/sqlparser/testdata/select_cases.txt @@ -17491,8 +17491,8 @@ END INPUT select 1 from t1 where 1 < some (select cast(a as datetime) from t1); END -ERROR -syntax error at position 40 near 'select' +OUTPUT +select 1 from t1 where 1 < any (select cast(a as datetime) from t1) END INPUT select hex(a) from t1 where a like 'A_' order by a; diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json index c6a91350d89..2fa0df2a847 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json @@ -4747,6 +4747,52 @@ ] } }, + { + "comment": "SOME modifier on unsharded table works well", + "query": "select 1 from unsharded where foo = SOME (select 1 from unsharded_a where foo = 1)", + "plan": { + "QueryType": "SELECT", + "Original": "select 1 from unsharded where foo = SOME (select 1 from unsharded_a where foo = 1)", + "Instructions": { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select 1 from unsharded where 1 != 1", + "Query": "select 1 from unsharded where foo = any (select 1 from unsharded_a where foo = 1)", + "Table": "unsharded, unsharded_a" + }, + "TablesUsed": [ + "main.unsharded", + "main.unsharded_a" + ] + } + }, + { + "comment": "ALL modifier on unsharded table works well", + "query": "select 1 from unsharded where foo = ALL (select 1 from unsharded_a where foo = 1)", + "plan": { + "QueryType": "SELECT", + "Original": "select 1 from unsharded where foo = ALL (select 1 from unsharded_a where foo = 1)", + "Instructions": { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select 1 from unsharded where 1 != 1", + "Query": "select 1 from unsharded where foo = all (select 1 from unsharded_a where foo = 1)", + "Table": "unsharded, unsharded_a" + }, + "TablesUsed": [ + "main.unsharded", + "main.unsharded_a" + ] + } + }, { "comment": "allow last_insert_id with argument", "query": "select last_insert_id(id) from user", diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json index 251af436d27..a8fd082eb7b 100644 --- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json @@ -358,5 +358,20 @@ "comment": "WITH ROLLUP not supported on sharded queries", "query": "select a, b, c, sum(d) from user group by a, b, c with rollup", "plan": "VT12001: unsupported: GROUP BY WITH ROLLUP not supported for sharded queries" + }, + { + "comment": "SOME/ANY/ALL comparison operator not supported for unsharded queries", + "query": "select 1 from user where foo = SOME (select 1 from user_extra where foo = 1)", + "plan": "VT12001: unsupported: ANY/ALL/SOME comparison operator" + }, + { + "comment": "SOME/ANY/ALL comparison operator not supported for unsharded queries", + "query": "select 1 from user where foo = ANY (select 1 from user_extra where foo = 1)", + "plan": "VT12001: unsupported: ANY/ALL/SOME comparison operator" + }, + { + "comment": "SOME/ANY/ALL comparison operator not supported for unsharded queries", + "query": "select 1 from user where foo = ALL (select 1 from user_extra where foo = 1)", + "plan": "VT12001: unsupported: ANY/ALL/SOME comparison operator" } ] diff --git a/go/vt/vtgate/semantics/analyzer.go b/go/vt/vtgate/semantics/analyzer.go index c771e541923..8bb7cc393fc 100644 --- a/go/vt/vtgate/semantics/analyzer.go +++ b/go/vt/vtgate/semantics/analyzer.go @@ -43,7 +43,7 @@ type analyzer struct { err error inProjection int - projErr error + notSingleRouteErr error unshardedErr error warning string canShortcut bool @@ -143,7 +143,7 @@ func (a *analyzer) newSemTable( Warning: a.warning, Collation: coll, ExprTypes: map[sqlparser.Expr]evalengine.Type{}, - NotSingleRouteErr: a.projErr, + NotSingleRouteErr: a.notSingleRouteErr, NotUnshardedErr: a.unshardedErr, Recursive: ExprDependencies{}, Direct: ExprDependencies{}, @@ -175,7 +175,7 @@ func (a *analyzer) newSemTable( ExprTypes: a.typer.m, Tables: a.tables.Tables, Targets: a.binder.targets, - NotSingleRouteErr: a.projErr, + NotSingleRouteErr: a.notSingleRouteErr, NotUnshardedErr: a.unshardedErr, Warning: a.warning, Comments: comments, @@ -194,13 +194,13 @@ func (a *analyzer) newSemTable( func (a *analyzer) setError(err error) { switch err := err.(type) { - case ProjError: - a.projErr = err.Inner + case NotSingleRouteErr: + a.notSingleRouteErr = err.Inner case ShardedError: a.unshardedErr = err.Inner default: if a.inProjection > 0 && vterrors.ErrState(err) == vterrors.NonUniqError { - a.projErr = err + a.notSingleRouteErr = err } else { a.err = err } @@ -464,8 +464,8 @@ func (a *analyzer) noteQuerySignature(node sqlparser.SQLNode) { // getError gets the error stored in the analyzer during previous phases. func (a *analyzer) getError() error { - if a.projErr != nil { - return a.projErr + if a.notSingleRouteErr != nil { + return a.notSingleRouteErr } if a.unshardedErr != nil { return a.unshardedErr @@ -473,13 +473,13 @@ func (a *analyzer) getError() error { return a.err } -// ProjError is used to mark an error as something that should only be returned +// NotSingleRouteErr is used to mark an error as something that should only be returned // if the planner fails to merge everything down to a single route -type ProjError struct { +type NotSingleRouteErr struct { Inner error } -func (p ProjError) Error() string { +func (p NotSingleRouteErr) Error() string { return p.Inner.Error() } diff --git a/go/vt/vtgate/semantics/binder.go b/go/vt/vtgate/semantics/binder.go index 8b4d6d2163d..90a36b1f0d7 100644 --- a/go/vt/vtgate/semantics/binder.go +++ b/go/vt/vtgate/semantics/binder.go @@ -451,7 +451,7 @@ func (b *binder) resolveColumnInScope(current *scope, expr *sqlparser.ColName, a } if deps, isUncertain := deps.(*uncertain); isUncertain && deps.fail { // if we have a failure from uncertain, we matched the column to multiple non-authoritative tables - return nil, ProjError{Inner: newAmbiguousColumnError(expr)} + return nil, NotSingleRouteErr{Inner: newAmbiguousColumnError(expr)} } return deps, nil } diff --git a/go/vt/vtgate/semantics/check_invalid.go b/go/vt/vtgate/semantics/check_invalid.go index 272bea9d9d0..a739e857c00 100644 --- a/go/vt/vtgate/semantics/check_invalid.go +++ b/go/vt/vtgate/semantics/check_invalid.go @@ -42,6 +42,10 @@ func (a *analyzer) checkForInvalidConstructs(cursor *sqlparser.Cursor) error { return checkDerived(node) case *sqlparser.AssignmentExpr: return vterrors.VT12001("Assignment expression") + case *sqlparser.ComparisonExpr: + if node.Modifier != sqlparser.Missing { + return NotSingleRouteErr{Inner: &UnsupportedConstruct{errString: "ANY/ALL/SOME comparison operator"}} + } case *sqlparser.Subquery: return a.checkSubqueryColumns(cursor.Parent(), node) case *sqlparser.With: From a55dc3efc3d622c17f118759158816e6205b6993 Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Tue, 11 Jun 2024 16:04:08 +0200 Subject: [PATCH 17/40] Add `timvaillancourt` to some `CODEOWNERS` paths (#16107) Signed-off-by: Tim Vaillancourt --- .github/CODEOWNERS | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 97eee33ca1c..8ba27ae6f54 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -28,9 +28,9 @@ go.sum @ajm188 @deepthi @harshit-gangal @mattlord @rohit-nayak-ps @systay @froui /go/test/endtoend/onlineddl @rohit-nayak-ps @shlomi-noach /go/test/endtoend/messaging @mattlord @rohit-nayak-ps @derekperkins /go/test/endtoend/schemadiff @shlomi-noach @mattlord -/go/test/endtoend/*throttler* @shlomi-noach @mattlord +/go/test/endtoend/*throttler* @shlomi-noach @mattlord @timvaillancourt /go/test/endtoend/vtgate @harshit-gangal @systay @frouioui -/go/test/endtoend/vtorc @deepthi @shlomi-noach @GuptaManan100 +/go/test/endtoend/vtorc @deepthi @shlomi-noach @GuptaManan100 @timvaillancourt /go/tools/ @frouioui @systay /go/vt/dbconnpool @harshit-gangal @mattlord /go/vt/discovery @deepthi @frouioui @@ -61,18 +61,18 @@ go.sum @ajm188 @deepthi @harshit-gangal @mattlord @rohit-nayak-ps @systay @froui /go/vt/vtgate/endtoend/*vstream* @rohit-nayak-ps @mattlord /go/vt/vtgate/planbuilder @harshit-gangal @systay @frouioui @GuptaManan100 @arthurschreiber /go/vt/vtgate/*vstream* @rohit-nayak-ps @mattlord -/go/vt/vtorc @deepthi @shlomi-noach @GuptaManan100 +/go/vt/vtorc @deepthi @shlomi-noach @GuptaManan100 @timvaillancourt /go/vt/vttablet/*conn* @harshit-gangal @systay /go/vt/vttablet/endtoend @harshit-gangal @mattlord @rohit-nayak-ps @systay /go/vt/vttablet/grpc* @ajm188 @rohit-nayak-ps @shlomi-noach @harshit-gangal /go/vt/vttablet/onlineddl @mattlord @rohit-nayak-ps @shlomi-noach /go/vt/vttablet/queryservice @harshit-gangal @systay /go/vt/vttablet/tabletmanager @deepthi @GuptaManan100 @rohit-nayak-ps @shlomi-noach -/go/vt/vttablet/tabletmanager/rpc_throttler.go @shlomi-noach @mattlord -/go/vt/vttablet/tabletserver/throttle @shlomi-noach @mattlord +/go/vt/vttablet/tabletmanager/rpc_throttler.go @shlomi-noach @mattlord @timvaillancourt +/go/vt/vttablet/tabletserver/throttle @shlomi-noach @mattlord @timvaillancourt /go/vt/vttablet/tabletmanager/vreplication @rohit-nayak-ps @mattlord /go/vt/vttablet/tabletmanager/vstreamer @rohit-nayak-ps @mattlord -/go/vt/vttablet/tabletserver* @harshit-gangal @systay @shlomi-noach @rohit-nayak-ps +/go/vt/vttablet/tabletserver* @harshit-gangal @systay @shlomi-noach @rohit-nayak-ps @timvaillancourt /go/vt/vttablet/tabletserver/messager @mattlord @rohit-nayak-ps @derekperkins /go/vt/vttablet/*tmclient* @ajm188 @GuptaManan100 @rohit-nayak-ps @shlomi-noach /go/vt/vttablet/vexec @mattlord @rohit-nayak-ps @shlomi-noach From 5d4a3fa8375ff91f52e28b53461efa95a44d53f4 Mon Sep 17 00:00:00 2001 From: Florent Poinsard <35779988+frouioui@users.noreply.github.com> Date: Tue, 11 Jun 2024 11:59:23 -0600 Subject: [PATCH 18/40] Fix the email in `pom.xml` (#16111) Signed-off-by: Florent Poinsard --- java/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index ce6a35503eb..079f185ad70 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -35,7 +35,7 @@ Placeholder entry representing all developers. Please reach out to our mailing list for questions. - vitess@googlegroups.com + cncf-vitess-maintainers@lists.cncf.io Vitess http://vitess.io @@ -59,7 +59,7 @@ - https://groups.google.com/forum/#!forum/vitess + cncf-vitess-maintainers@lists.cncf.io From e0325be4f8ddbaad1cc1c9fa48b149f17ddd491f Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Tue, 11 Jun 2024 21:52:42 +0200 Subject: [PATCH 19/40] Ensure that we check the correct collation for foreign keys (#16109) Signed-off-by: Dirkjan Bussink --- go/vt/schemadiff/schema.go | 75 ++++++++++++++++++++++----------- go/vt/schemadiff/schema_test.go | 20 +++++++++ 2 files changed, 70 insertions(+), 25 deletions(-) diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index 1738b9a4836..df1e23f0ccc 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -359,30 +359,6 @@ func (s *Schema) normalize(hints *DiffHints) error { return errors.Join(errs, err) } } - colTypeCompatibleForForeignKey := func(child, parent *sqlparser.ColumnType) bool { - if child.Type == parent.Type { - return true - } - if child.Type == "char" && parent.Type == "varchar" { - return true - } - if child.Type == "varchar" && parent.Type == "char" { - return true - } - return false - } - colTypeEqualForForeignKey := func(child, parent *sqlparser.ColumnType) bool { - if colTypeCompatibleForForeignKey(child, parent) && - child.Unsigned == parent.Unsigned && - child.Zerofill == parent.Zerofill && - sqlparser.Equals.ColumnCharset(child.Charset, parent.Charset) && - child.Options.Collate == parent.Options.Collate && - sqlparser.Equals.SliceOfString(child.EnumValues, parent.EnumValues) { - // Complete identify (other than precision which is ignored) - return true - } - return false - } // Now validate foreign key columns: // - referenced table columns must exist @@ -429,7 +405,7 @@ func (s *Schema) normalize(hints *DiffHints) error { if !ok { return errors.Join(errs, &InvalidReferencedColumnInForeignKeyConstraintError{Table: t.Name(), Constraint: cs.Name.String(), ReferencedTable: referencedTableName, ReferencedColumn: referencedColumnName}) } - if !colTypeEqualForForeignKey(coveredColumn.Type, referencedColumn.Type) { + if !colTypeEqualForForeignKey(s.env, t.TableSpec, referencedTable.CreateTable.TableSpec, coveredColumn.Type, referencedColumn.Type) { return errors.Join(errs, &ForeignKeyColumnTypeMismatchError{Table: t.Name(), Constraint: cs.Name.String(), Column: coveredColumn.Name.String(), ReferencedTable: referencedTableName, ReferencedColumn: referencedColumnName}) } } @@ -442,6 +418,55 @@ func (s *Schema) normalize(hints *DiffHints) error { return errs } +func colTypeCompatibleForForeignKey(child, parent *sqlparser.ColumnType) bool { + if child.Type == parent.Type { + return true + } + if child.Type == "char" && parent.Type == "varchar" { + return true + } + if child.Type == "varchar" && parent.Type == "char" { + return true + } + return false +} + +func colTypeEqualForForeignKey(env *Environment, ct, pt *sqlparser.TableSpec, child, parent *sqlparser.ColumnType) bool { + if colTypeCompatibleForForeignKey(child, parent) && + child.Unsigned == parent.Unsigned && + child.Zerofill == parent.Zerofill && + colCollationEqualForForeignKey(env, ct, pt, child, parent) && + sqlparser.Equals.SliceOfString(child.EnumValues, parent.EnumValues) { + // Complete identify (other than precision which is ignored) + return true + } + return false +} + +func colCollationEqualForForeignKey(env *Environment, ct, pt *sqlparser.TableSpec, child, parent *sqlparser.ColumnType) bool { + return *colCollation(env, ct, child) == *colCollation(env, pt, parent) +} + +func colCollation(env *Environment, t *sqlparser.TableSpec, col *sqlparser.ColumnType) *charsetCollate { + tc := getTableCharsetCollate(env, &t.Options) + cc := &charsetCollate{} + if col.Charset.Name != "" { + cc.charset = col.Charset.Name + } else if tc.charset != "" { + cc.charset = tc.charset + } else { + cc.charset = env.CollationEnv().LookupCharsetName(env.DefaultColl) + } + if col.Options != nil && col.Options.Collate != "" { + cc.collate = col.Options.Collate + } else if tc.collate != "" { + cc.collate = tc.collate + } else { + cc.collate = env.CollationEnv().LookupName(env.DefaultColl) + } + return cc +} + // Entities returns this schema's entities in good order (may be applied without error) func (s *Schema) Entities() []Entity { return s.sorted diff --git a/go/vt/schemadiff/schema_test.go b/go/vt/schemadiff/schema_test.go index 23782e676a1..c35cc224714 100644 --- a/go/vt/schemadiff/schema_test.go +++ b/go/vt/schemadiff/schema_test.go @@ -480,6 +480,26 @@ func TestInvalidSchema(t *testing.T) { schema: "create table t10(id VARCHAR(50) charset utf8mb4 collate utf8mb4_0900_ai_ci primary key); create table t11 (id int primary key, i VARCHAR(100) charset utf8mb4 collate utf8mb4_general_ci, key ix(i), constraint f10 foreign key (i) references t10(id) on delete restrict)", expectErr: &ForeignKeyColumnTypeMismatchError{Table: "t11", Constraint: "f10", Column: "i", ReferencedTable: "t10", ReferencedColumn: "id"}, }, + { + schema: "create table post (id varchar(191) not null, `title` text, primary key (`id`)); create table post_fks (id varchar(191) not null, `post_id` varchar(191) collate utf8mb4_0900_ai_ci not null, primary key (id), constraint post_fk foreign key (post_id) references post (id)) charset utf8mb4, collate utf8mb4_0900_as_ci;", + }, + { + schema: "create table post (id varchar(191) not null, `title` text, primary key (`id`)); create table post_fks (id varchar(191) not null, `post_id` varchar(191) collate utf8mb4_0900_ai_ci not null, primary key (id), constraint post_fk foreign key (post_id) references post (id)) collate utf8mb4_0900_as_ci;", + }, + { + schema: "create table post (id varchar(191) not null, `title` text, primary key (`id`)); create table post_fks (id varchar(191) not null, `post_id` varchar(191) collate utf8mb4_0900_ai_ci not null, primary key (id), constraint post_fk foreign key (post_id) references post (id)) charset utf8mb4;", + }, + { + schema: "create table post (id varchar(191) not null, `title` text, primary key (`id`)); create table post_fks (id varchar(191) not null, `post_id` varchar(191), primary key (id), constraint post_fk foreign key (post_id) references post (id)) charset utf8mb4, collate utf8mb4_0900_as_ci;", + expectErr: &ForeignKeyColumnTypeMismatchError{Table: "post_fks", Constraint: "post_fk", Column: "post_id", ReferencedTable: "post", ReferencedColumn: "id"}, + }, + { + schema: "create table post (id varchar(191) charset utf8mb4 not null, `title` text, primary key (`id`)); create table post_fks (id varchar(191) not null, `post_id` varchar(191), primary key (id), constraint post_fk foreign key (post_id) references post (id)) charset utf8mb4, collate utf8mb4_0900_as_ci;", + expectErr: &ForeignKeyColumnTypeMismatchError{Table: "post_fks", Constraint: "post_fk", Column: "post_id", ReferencedTable: "post", ReferencedColumn: "id"}, + }, + { + schema: "create table post (id varchar(191) charset utf8mb4 not null, `title` text, primary key (`id`)); create table post_fks (id varchar(191) not null, `post_id` varchar(191) collate utf8mb4_0900_ai_ci, primary key (id), constraint post_fk foreign key (post_id) references post (id)) charset utf8mb4, collate utf8mb4_0900_as_ci;", + }, } for _, ts := range tt { t.Run(ts.schema, func(t *testing.T) { From 4f04b8b11e8b1dbc12aa187a5f53e8ed3b69b3f1 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Wed, 12 Jun 2024 03:39:50 +0530 Subject: [PATCH 20/40] Deprecated metrics deletion (#16086) Signed-off-by: Manan Gupta --- changelog/21.0/21.0.0/summary.md | 36 +++++++ changelog/21.0/README.md | 2 + changelog/README.md | 1 + go/stats/counter.go | 33 ------- go/stats/counter_test.go | 95 ------------------- go/stats/counters.go | 16 ---- go/stats/counters_test.go | 49 ---------- go/stats/timings.go | 16 ---- go/stats/timings_test.go | 49 ---------- go/test/endtoend/vtorc/api/api_test.go | 12 --- .../primaryfailure/primary_failure_test.go | 6 -- go/test/endtoend/vtorc/utils/utils.go | 8 +- .../reparentutil/emergency_reparenter.go | 2 +- .../vtctl/reparentutil/planned_reparenter.go | 2 +- go/vt/vtctl/reparentutil/util.go | 2 +- go/vt/vtorc/inst/analysis_dao.go | 3 +- go/vt/vtorc/inst/audit_dao.go | 3 +- go/vt/vtorc/inst/instance_dao.go | 5 +- go/vt/vtorc/logic/vtorc.go | 11 +-- 19 files changed, 55 insertions(+), 296 deletions(-) create mode 100644 changelog/21.0/21.0.0/summary.md create mode 100644 changelog/21.0/README.md diff --git a/changelog/21.0/21.0.0/summary.md b/changelog/21.0/21.0.0/summary.md new file mode 100644 index 00000000000..1d894120cae --- /dev/null +++ b/changelog/21.0/21.0.0/summary.md @@ -0,0 +1,36 @@ + +## Summary + +### Table of Contents + +- **[Major Changes](#major-changes)** + - **[Deletions](#deletions)** + - [Deletion of deprecated metrics](#metric-deletion) + - **[Breaking changes](#breaking-changes)** + +## Major Changes + +### Deletion + +#### Deletion of deprecated metrics + +The following metrics that were deprecated in the previous release, have now been deleted. + + +| Metric Name | +|:--------------------------------------------:| +| `analysis.change.write` | +| `audit.write` | +| `discoveries.attempt` | +| `discoveries.fail` | +| `discoveries.instance_poll_seconds_exceeded` | +| `discoveries.queue_length` | +| `discoveries.recent_count` | +| `instance.read` | +| `instance.read_topology` | +| `emergency_reparent_counts` | +| `planned_reparent_counts` | +| `reparent_shard_operation_timings` | + + + diff --git a/changelog/21.0/README.md b/changelog/21.0/README.md new file mode 100644 index 00000000000..bade1b597f8 --- /dev/null +++ b/changelog/21.0/README.md @@ -0,0 +1,2 @@ +## v21.0 +* **[21.0.0](21.0.0)** diff --git a/changelog/README.md b/changelog/README.md index 3a55d986643..9feda6440c6 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -1,4 +1,5 @@ ## Releases +* [21.0](21.0) * [20.0](20.0) * [19.0](19.0) * [18.0](18.0) diff --git a/go/stats/counter.go b/go/stats/counter.go index e74969039f6..4428dfe1136 100644 --- a/go/stats/counter.go +++ b/go/stats/counter.go @@ -17,8 +17,6 @@ limitations under the License. package stats import ( - "expvar" - "fmt" "math" "strconv" "sync/atomic" @@ -47,22 +45,6 @@ func NewCounter(name string, help string) *Counter { return v } -// NewCounterWithDeprecatedName returns a new Counter that also has a deprecated name that can be removed in a future release. -// It is important to ensure that we only call this function with values for name and deprecatedName such that they match to the same -// metric name in snake case. -func NewCounterWithDeprecatedName(name string, deprecatedName string, help string) *Counter { - // Ensure that the snake case for the deprecated name and the new name are the same. - if deprecatedName == "" || GetSnakeName(name) != GetSnakeName(deprecatedName) { - panic(fmt.Sprintf("New name for deprecated metric doesn't have the same snake case - %v", deprecatedName)) - } - - v := NewCounter(deprecatedName, help) - // We have already published the deprecated name for backward compatibility. - // At the same time we want the new metric to be visible on the `/debug/vars` page, so we publish the new name in expvar. - expvar.Publish(name, v) - return v -} - // Add adds the provided value to the Counter. func (v *Counter) Add(delta int64) { if delta < 0 { @@ -154,21 +136,6 @@ func NewGauge(name string, help string) *Gauge { return v } -// NewGaugeWithDeprecatedName creates a new Gauge and publishes it if name is set that also has a deprecated name that can be removed in a future release. -// It is important to ensure that we only call this function with values for name and deprecatedName such that they match to the same metric name in snake case. -func NewGaugeWithDeprecatedName(name string, deprecatedName string, help string) *Gauge { - // Ensure that the snake case for the deprecated name and the new name are the same. - if deprecatedName == "" || GetSnakeName(name) != GetSnakeName(deprecatedName) { - panic(fmt.Sprintf("New name for deprecated metric doesn't have the same snake case - %v", deprecatedName)) - } - - v := NewGauge(deprecatedName, help) - // We have already published the deprecated name for backward compatibility. - // At the same time we want the new metric to be visible on the `/debug/vars` page, so we publish the new name in expvar. - expvar.Publish(name, v) - return v -} - // Set overwrites the current value. func (v *Gauge) Set(value int64) { v.Counter.i.Store(value) diff --git a/go/stats/counter_test.go b/go/stats/counter_test.go index 6a7b496dfab..f290dc733d7 100644 --- a/go/stats/counter_test.go +++ b/go/stats/counter_test.go @@ -18,12 +18,9 @@ package stats import ( "expvar" - "fmt" - "sync" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestCounter(t *testing.T) { @@ -94,95 +91,3 @@ func TestGaugeFloat64(t *testing.T) { v.Reset() assert.Equal(t, float64(0), v.Get()) } - -func TestNewCounterWithDeprecatedName(t *testing.T) { - clearStats() - Register(func(name string, v expvar.Var) {}) - - testcases := []struct { - name string - deprecatedName string - shouldPanic bool - }{ - { - name: "new_name", - deprecatedName: "deprecatedName", - shouldPanic: true, - }, - { - name: "metricName_test", - deprecatedName: "metric.name-test", - shouldPanic: false, - }, - { - name: "MetricNameTesting", - deprecatedName: "metric.name.testing", - shouldPanic: false, - }, - } - - for _, testcase := range testcases { - t.Run(fmt.Sprintf("%v-%v", testcase.name, testcase.deprecatedName), func(t *testing.T) { - wg := sync.WaitGroup{} - wg.Add(1) - panicReceived := false - go func() { - defer func() { - if x := recover(); x != nil { - panicReceived = true - } - wg.Done() - }() - NewCounterWithDeprecatedName(testcase.name, testcase.deprecatedName, "help") - }() - wg.Wait() - require.EqualValues(t, testcase.shouldPanic, panicReceived) - }) - } -} - -func TestNewGaugeWithDeprecatedName(t *testing.T) { - clearStats() - Register(func(name string, v expvar.Var) {}) - - testcases := []struct { - name string - deprecatedName string - shouldPanic bool - }{ - { - name: "gauge_new_name", - deprecatedName: "gauge_deprecatedName", - shouldPanic: true, - }, - { - name: "gauge-metricName_test", - deprecatedName: "gauge_metric.name-test", - shouldPanic: false, - }, - { - name: "GaugeMetricNameTesting", - deprecatedName: "gauge.metric.name.testing", - shouldPanic: false, - }, - } - - for _, testcase := range testcases { - t.Run(fmt.Sprintf("%v-%v", testcase.name, testcase.deprecatedName), func(t *testing.T) { - wg := sync.WaitGroup{} - wg.Add(1) - panicReceived := false - go func() { - defer func() { - if x := recover(); x != nil { - panicReceived = true - } - wg.Done() - }() - NewGaugeWithDeprecatedName(testcase.name, testcase.deprecatedName, "help") - }() - wg.Wait() - require.EqualValues(t, testcase.shouldPanic, panicReceived) - }) - } -} diff --git a/go/stats/counters.go b/go/stats/counters.go index b3099993b09..bcf7fc3a8b6 100644 --- a/go/stats/counters.go +++ b/go/stats/counters.go @@ -18,7 +18,6 @@ package stats import ( "bytes" - "expvar" "fmt" "strings" "sync" @@ -186,21 +185,6 @@ func NewCountersWithMultiLabels(name, help string, labels []string) *CountersWit return t } -// NewCountersWithMultiLabelsWithDeprecatedName returns a new CountersWithMultiLabels that also has a deprecated name that can be removed in a future release. -// It is important to ensure that we only call this function with values for name and deprecatedName such that they match to the same -// metric name in snake case. -func NewCountersWithMultiLabelsWithDeprecatedName(name string, deprecatedName string, help string, labels []string) *CountersWithMultiLabels { - // Ensure that the snake case for the deprecated name and the new name are the same. - if deprecatedName == "" || GetSnakeName(name) != GetSnakeName(deprecatedName) { - panic(fmt.Sprintf("New name for deprecated metric doesn't have the same snake case - %v", deprecatedName)) - } - t := NewCountersWithMultiLabels(deprecatedName, help, labels) - // We have already published the deprecated name for backward compatibility. - // At the same time we want the new metric to be visible on the `/debug/vars` page, so we publish the new name in expvar. - expvar.Publish(name, t) - return t -} - // Labels returns the list of labels. func (mc *CountersWithMultiLabels) Labels() []string { return mc.labels diff --git a/go/stats/counters_test.go b/go/stats/counters_test.go index e1b171a2765..72eb11e1a10 100644 --- a/go/stats/counters_test.go +++ b/go/stats/counters_test.go @@ -18,17 +18,14 @@ package stats import ( "expvar" - "fmt" "math/rand/v2" "reflect" "sort" "strings" - "sync" "testing" "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestCounters(t *testing.T) { @@ -272,49 +269,3 @@ func TestCountersCombineDimension(t *testing.T) { c4.Add([]string{"c4", "c2", "c5"}, 1) assert.Equal(t, `{"all.c2.all": 2}`, c4.String()) } - -func TestNewCountersWithMultiLabelsWithDeprecatedName(t *testing.T) { - clearStats() - Register(func(name string, v expvar.Var) {}) - - testcases := []struct { - name string - deprecatedName string - shouldPanic bool - }{ - { - name: "counterWithMultiLabels_new_name", - deprecatedName: "counterWithMultiLabels_deprecatedName", - shouldPanic: true, - }, - { - name: "counterWithMultiLabels-metricName_test", - deprecatedName: "counterWithMultiLabels_metric.name-test", - shouldPanic: false, - }, - { - name: "CounterWithMultiLabelsMetricNameTesting", - deprecatedName: "counterWithMultiLabels.metric.name.testing", - shouldPanic: false, - }, - } - - for _, testcase := range testcases { - t.Run(fmt.Sprintf("%v-%v", testcase.name, testcase.deprecatedName), func(t *testing.T) { - wg := sync.WaitGroup{} - wg.Add(1) - panicReceived := false - go func() { - defer func() { - if x := recover(); x != nil { - panicReceived = true - } - wg.Done() - }() - NewCountersWithMultiLabelsWithDeprecatedName(testcase.name, testcase.deprecatedName, "help", []string{"1", "2", "3"}) - }() - wg.Wait() - require.EqualValues(t, testcase.shouldPanic, panicReceived) - }) - } -} diff --git a/go/stats/timings.go b/go/stats/timings.go index 9742ad4d67c..d0fb82ebedf 100644 --- a/go/stats/timings.go +++ b/go/stats/timings.go @@ -18,7 +18,6 @@ package stats import ( "encoding/json" - "expvar" "fmt" "sync" "sync/atomic" @@ -62,21 +61,6 @@ func NewTimings(name, help, label string, categories ...string) *Timings { return t } -// NewTimingsWithDeprecatedName returns a new Timings that also has a deprecated name that can be removed in a future release. -// It is important to ensure that we only call this function with values for name and deprecatedName such that they match to the same -// metric name in snake case. -func NewTimingsWithDeprecatedName(name string, deprecatedName string, help, label string, categories ...string) *Timings { - // Ensure that the snake case for the deprecated name and the new name are the same. - if deprecatedName == "" || GetSnakeName(name) != GetSnakeName(deprecatedName) { - panic(fmt.Sprintf("New name for deprecated metric doesn't have the same snake case - %v", deprecatedName)) - } - t := NewTimings(deprecatedName, help, label, categories...) - // We have already published the deprecated name for backward compatibility. - // At the same time we want the new metric to be visible on the `/debug/vars` page, so we publish the new name in expvar. - expvar.Publish(name, t) - return t -} - // Reset will clear histograms and counters: used during testing func (t *Timings) Reset() { t.mu.RLock() diff --git a/go/stats/timings_test.go b/go/stats/timings_test.go index 518d38947e5..a632f3fba6a 100644 --- a/go/stats/timings_test.go +++ b/go/stats/timings_test.go @@ -18,14 +18,11 @@ package stats import ( "expvar" - "fmt" "strings" - "sync" "testing" "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestTimings(t *testing.T) { @@ -102,49 +99,3 @@ func TestTimingsCombineDimension(t *testing.T) { want = `{"TotalCount":1,"TotalTime":1,"Histograms":{"all.c2.all":{"500000":1,"1000000":0,"5000000":0,"10000000":0,"50000000":0,"100000000":0,"500000000":0,"1000000000":0,"5000000000":0,"10000000000":0,"inf":0,"Count":1,"Time":1}}}` assert.Equal(t, want, t3.String()) } - -func TestNewTimingsWithDeprecatedName(t *testing.T) { - clearStats() - Register(func(name string, v expvar.Var) {}) - - testcases := []struct { - name string - deprecatedName string - shouldPanic bool - }{ - { - name: "timings_new_name", - deprecatedName: "timings_deprecatedName", - shouldPanic: true, - }, - { - name: "timings-metricName_test", - deprecatedName: "timings_metric.name-test", - shouldPanic: false, - }, - { - name: "TimingsMetricNameTesting", - deprecatedName: "timings.metric.name.testing", - shouldPanic: false, - }, - } - - for _, testcase := range testcases { - t.Run(fmt.Sprintf("%v-%v", testcase.name, testcase.deprecatedName), func(t *testing.T) { - wg := sync.WaitGroup{} - wg.Add(1) - panicReceived := false - go func() { - defer func() { - if x := recover(); x != nil { - panicReceived = true - } - wg.Done() - }() - NewTimingsWithDeprecatedName(testcase.name, testcase.deprecatedName, "help", "label", []string{"1", "2", "3"}...) - }() - wg.Wait() - require.EqualValues(t, testcase.shouldPanic, panicReceived) - }) - } -} diff --git a/go/test/endtoend/vtorc/api/api_test.go b/go/test/endtoend/vtorc/api/api_test.go index 8fa24a39ac7..174ee5ea914 100644 --- a/go/test/endtoend/vtorc/api/api_test.go +++ b/go/test/endtoend/vtorc/api/api_test.go @@ -110,18 +110,6 @@ func TestAPIEndpoints(t *testing.T) { }) t.Run("Check Vars and Metrics", func(t *testing.T) { - // These are vars that will be deprecated in v21. - utils.CheckVarExists(t, vtorc, "analysis.change.write") - utils.CheckVarExists(t, vtorc, "audit.write") - utils.CheckVarExists(t, vtorc, "discoveries.attempt") - utils.CheckVarExists(t, vtorc, "discoveries.fail") - utils.CheckVarExists(t, vtorc, "discoveries.instance_poll_seconds_exceeded") - utils.CheckVarExists(t, vtorc, "discoveries.queue_length") - utils.CheckVarExists(t, vtorc, "discoveries.recent_count") - utils.CheckVarExists(t, vtorc, "instance.read") - utils.CheckVarExists(t, vtorc, "instance.read_topology") - - // Newly added vars. utils.CheckVarExists(t, vtorc, "AnalysisChangeWrite") utils.CheckVarExists(t, vtorc, "AuditWrite") utils.CheckVarExists(t, vtorc, "DiscoveriesAttempt") diff --git a/go/test/endtoend/vtorc/primaryfailure/primary_failure_test.go b/go/test/endtoend/vtorc/primaryfailure/primary_failure_test.go index 645b413799c..886aa3a580a 100644 --- a/go/test/endtoend/vtorc/primaryfailure/primary_failure_test.go +++ b/go/test/endtoend/vtorc/primaryfailure/primary_failure_test.go @@ -102,12 +102,6 @@ func TestDownPrimary(t *testing.T) { utils.WaitForSuccessfulRecoveryCount(t, vtOrcProcess, logic.RecoverDeadPrimaryRecoveryName, 1) utils.WaitForSuccessfulERSCount(t, vtOrcProcess, keyspace.Name, shard0.Name, 1) t.Run("Check ERS and PRS Vars and Metrics", func(t *testing.T) { - // These are vars that will be deprecated in v21. - utils.CheckVarExists(t, vtOrcProcess, "emergency_reparent_counts") - utils.CheckVarExists(t, vtOrcProcess, "planned_reparent_counts") - utils.CheckVarExists(t, vtOrcProcess, "reparent_shard_operation_timings") - - // Newly added vars utils.CheckVarExists(t, vtOrcProcess, "EmergencyReparentCounts") utils.CheckVarExists(t, vtOrcProcess, "PlannedReparentCounts") utils.CheckVarExists(t, vtOrcProcess, "ReparentShardOperationTimings") diff --git a/go/test/endtoend/vtorc/utils/utils.go b/go/test/endtoend/vtorc/utils/utils.go index 5982589af85..63500377f47 100644 --- a/go/test/endtoend/vtorc/utils/utils.go +++ b/go/test/endtoend/vtorc/utils/utils.go @@ -1018,7 +1018,7 @@ func WaitForSuccessfulPRSCount(t *testing.T, vtorcInstance *cluster.VTOrcProcess mapKey := fmt.Sprintf("%v.%v.success", keyspace, shard) for time.Since(startTime) < timeout { vars := vtorcInstance.GetVars() - prsCountsMap := vars["planned_reparent_counts"].(map[string]interface{}) + prsCountsMap := vars["PlannedReparentCounts"].(map[string]interface{}) successCount := getIntFromValue(prsCountsMap[mapKey]) if successCount == countExpected { return @@ -1026,7 +1026,7 @@ func WaitForSuccessfulPRSCount(t *testing.T, vtorcInstance *cluster.VTOrcProcess time.Sleep(time.Second) } vars := vtorcInstance.GetVars() - prsCountsMap := vars["planned_reparent_counts"].(map[string]interface{}) + prsCountsMap := vars["PlannedReparentCounts"].(map[string]interface{}) successCount := getIntFromValue(prsCountsMap[mapKey]) assert.EqualValues(t, countExpected, successCount) } @@ -1039,7 +1039,7 @@ func WaitForSuccessfulERSCount(t *testing.T, vtorcInstance *cluster.VTOrcProcess mapKey := fmt.Sprintf("%v.%v.success", keyspace, shard) for time.Since(startTime) < timeout { vars := vtorcInstance.GetVars() - ersCountsMap := vars["emergency_reparent_counts"].(map[string]interface{}) + ersCountsMap := vars["EmergencyReparentCounts"].(map[string]interface{}) successCount := getIntFromValue(ersCountsMap[mapKey]) if successCount == countExpected { return @@ -1047,7 +1047,7 @@ func WaitForSuccessfulERSCount(t *testing.T, vtorcInstance *cluster.VTOrcProcess time.Sleep(time.Second) } vars := vtorcInstance.GetVars() - ersCountsMap := vars["emergency_reparent_counts"].(map[string]interface{}) + ersCountsMap := vars["EmergencyReparentCounts"].(map[string]interface{}) successCount := getIntFromValue(ersCountsMap[mapKey]) assert.EqualValues(t, countExpected, successCount) } diff --git a/go/vt/vtctl/reparentutil/emergency_reparenter.go b/go/vt/vtctl/reparentutil/emergency_reparenter.go index d7e5b8a8445..60e423c502c 100644 --- a/go/vt/vtctl/reparentutil/emergency_reparenter.go +++ b/go/vt/vtctl/reparentutil/emergency_reparenter.go @@ -68,7 +68,7 @@ type EmergencyReparentOptions struct { } // counters for Emergency Reparent Shard -var ersCounter = stats.NewCountersWithMultiLabelsWithDeprecatedName("EmergencyReparentCounts", "emergency_reparent_counts", "Number of times Emergency Reparent Shard has been run", +var ersCounter = stats.NewCountersWithMultiLabels("EmergencyReparentCounts", "Number of times Emergency Reparent Shard has been run", []string{"Keyspace", "Shard", "Result"}, ) diff --git a/go/vt/vtctl/reparentutil/planned_reparenter.go b/go/vt/vtctl/reparentutil/planned_reparenter.go index 3ef327987e3..c311a5c836c 100644 --- a/go/vt/vtctl/reparentutil/planned_reparenter.go +++ b/go/vt/vtctl/reparentutil/planned_reparenter.go @@ -41,7 +41,7 @@ import ( // counters for Planned Reparent Shard var ( - prsCounter = stats.NewCountersWithMultiLabelsWithDeprecatedName("PlannedReparentCounts", "planned_reparent_counts", "Number of times Planned Reparent Shard has been run", + prsCounter = stats.NewCountersWithMultiLabels("PlannedReparentCounts", "Number of times Planned Reparent Shard has been run", []string{"Keyspace", "Shard", "Result"}, ) ) diff --git a/go/vt/vtctl/reparentutil/util.go b/go/vt/vtctl/reparentutil/util.go index 4ea4d25ed83..5962ff9fa24 100644 --- a/go/vt/vtctl/reparentutil/util.go +++ b/go/vt/vtctl/reparentutil/util.go @@ -44,7 +44,7 @@ import ( ) var ( - reparentShardOpTimings = stats.NewTimingsWithDeprecatedName("ReparentShardOperationTimings", "reparent_shard_operation_timings", "Timings of reparent shard operations", "Operation") + reparentShardOpTimings = stats.NewTimings("ReparentShardOperationTimings", "Timings of reparent shard operations", "Operation") failureResult = "failure" successResult = "success" ) diff --git a/go/vt/vtorc/inst/analysis_dao.go b/go/vt/vtorc/inst/analysis_dao.go index b9bf1fba236..0268a8b183a 100644 --- a/go/vt/vtorc/inst/analysis_dao.go +++ b/go/vt/vtorc/inst/analysis_dao.go @@ -36,8 +36,7 @@ import ( "vitess.io/vitess/go/vt/vtorc/util" ) -// The metric is registered with a deprecated name. The old metric name can be removed in v21. -var analysisChangeWriteCounter = stats.NewCounterWithDeprecatedName("AnalysisChangeWrite", "analysis.change.write", "Number of times analysis has changed") +var analysisChangeWriteCounter = stats.NewCounter("AnalysisChangeWrite", "Number of times analysis has changed") var recentInstantAnalysis *cache.Cache diff --git a/go/vt/vtorc/inst/audit_dao.go b/go/vt/vtorc/inst/audit_dao.go index eb6eb226b70..d048f300faf 100644 --- a/go/vt/vtorc/inst/audit_dao.go +++ b/go/vt/vtorc/inst/audit_dao.go @@ -27,8 +27,7 @@ import ( "vitess.io/vitess/go/vt/vtorc/db" ) -// The metric is registered with a deprecated name. The old metric name can be removed in v21. -var auditOperationCounter = stats.NewCounterWithDeprecatedName("AuditWrite", "audit.write", "Number of audit operations performed") +var auditOperationCounter = stats.NewCounter("AuditWrite", "Number of audit operations performed") // AuditOperation creates and writes a new audit entry by given params func AuditOperation(auditType string, tabletAlias string, message string) error { diff --git a/go/vt/vtorc/inst/instance_dao.go b/go/vt/vtorc/inst/instance_dao.go index dddfcf640fe..0615cbc0cde 100644 --- a/go/vt/vtorc/inst/instance_dao.go +++ b/go/vt/vtorc/inst/instance_dao.go @@ -59,9 +59,8 @@ var ( var forgetAliases *cache.Cache var ( - // The metrics are registered with deprecated names. The old metric names can be removed in v21. - readTopologyInstanceCounter = stats.NewCounterWithDeprecatedName("InstanceReadTopology", "instance.read_topology", "Number of times an instance was read from the topology") - readInstanceCounter = stats.NewCounterWithDeprecatedName("InstanceRead", "instance.read", "Number of times an instance was read") + readTopologyInstanceCounter = stats.NewCounter("InstanceReadTopology", "Number of times an instance was read from the topology") + readInstanceCounter = stats.NewCounter("InstanceRead", "Number of times an instance was read") backendWrites = collection.CreateOrReturnCollection("BACKEND_WRITES") writeBufferLatency = stopwatch.NewNamedStopwatch() ) diff --git a/go/vt/vtorc/logic/vtorc.go b/go/vt/vtorc/logic/vtorc.go index 0e38f6e3aae..9a468d1508a 100644 --- a/go/vt/vtorc/logic/vtorc.go +++ b/go/vt/vtorc/logic/vtorc.go @@ -50,12 +50,11 @@ var snapshotDiscoveryKeys chan string var snapshotDiscoveryKeysMutex sync.Mutex var hasReceivedSIGTERM int32 -// The metrics are registered with deprecated names. The old metric names can be removed in v21. -var discoveriesCounter = stats.NewCounterWithDeprecatedName("DiscoveriesAttempt", "discoveries.attempt", "Number of discoveries attempted") -var failedDiscoveriesCounter = stats.NewCounterWithDeprecatedName("DiscoveriesFail", "discoveries.fail", "Number of failed discoveries") -var instancePollSecondsExceededCounter = stats.NewCounterWithDeprecatedName("DiscoveriesInstancePollSecondsExceeded", "discoveries.instance_poll_seconds_exceeded", "Number of instances that took longer than InstancePollSeconds to poll") -var discoveryQueueLengthGauge = stats.NewGaugeWithDeprecatedName("DiscoveriesQueueLength", "discoveries.queue_length", "Length of the discovery queue") -var discoveryRecentCountGauge = stats.NewGaugeWithDeprecatedName("DiscoveriesRecentCount", "discoveries.recent_count", "Number of recent discoveries") +var discoveriesCounter = stats.NewCounter("DiscoveriesAttempt", "Number of discoveries attempted") +var failedDiscoveriesCounter = stats.NewCounter("DiscoveriesFail", "Number of failed discoveries") +var instancePollSecondsExceededCounter = stats.NewCounter("DiscoveriesInstancePollSecondsExceeded", "Number of instances that took longer than InstancePollSeconds to poll") +var discoveryQueueLengthGauge = stats.NewGauge("DiscoveriesQueueLength", "Length of the discovery queue") +var discoveryRecentCountGauge = stats.NewGauge("DiscoveriesRecentCount", "Number of recent discoveries") var discoveryMetrics = collection.CreateOrReturnCollection(DiscoveryMetricsName) var recentDiscoveryOperationKeys *cache.Cache From 1c2d6da70c5f9f394aa3a1cf458c80cc34f8056d Mon Sep 17 00:00:00 2001 From: Frances Thai <31225471+notfelineit@users.noreply.github.com> Date: Tue, 11 Jun 2024 18:12:30 -0700 Subject: [PATCH 21/40] Update braces package (#16115) Signed-off-by: Frances Thai --- web/vtadmin/package-lock.json | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/web/vtadmin/package-lock.json b/web/vtadmin/package-lock.json index acf6d52cff7..a14da6bf0ee 100644 --- a/web/vtadmin/package-lock.json +++ b/web/vtadmin/package-lock.json @@ -6087,11 +6087,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -8718,9 +8719,10 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -9776,6 +9778,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -17216,6 +17219,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, From 8cf7f31d5981bbe6d338c96539b2a941d49848fd Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Wed, 12 Jun 2024 07:37:02 +0200 Subject: [PATCH 22/40] vtctldclient: Apply (Shard | Keyspace| Table) Routing Rules commands don't work (#16096) Signed-off-by: Rohit Nayak --- .../command/keyspace_routing_rules.go | 2 +- go/cmd/vtctldclient/command/routing_rules.go | 2 +- .../command/shard_routing_rules.go | 2 +- go/json2/unmarshal.go | 9 +- go/json2/unmarshal_test.go | 11 ++ .../vreplication_vtctldclient_cli_test.go | 140 ++++++++++++++++++ 6 files changed, 161 insertions(+), 5 deletions(-) diff --git a/go/cmd/vtctldclient/command/keyspace_routing_rules.go b/go/cmd/vtctldclient/command/keyspace_routing_rules.go index 7d1134d3abf..68aaa35b8bb 100644 --- a/go/cmd/vtctldclient/command/keyspace_routing_rules.go +++ b/go/cmd/vtctldclient/command/keyspace_routing_rules.go @@ -82,7 +82,7 @@ func commandApplyKeyspaceRoutingRules(cmd *cobra.Command, args []string) error { } krr := &vschemapb.KeyspaceRoutingRules{} - if err := json2.Unmarshal(rulesBytes, &krr); err != nil { + if err := json2.UnmarshalPB(rulesBytes, krr); err != nil { return err } diff --git a/go/cmd/vtctldclient/command/routing_rules.go b/go/cmd/vtctldclient/command/routing_rules.go index 0ffee0c2c24..8a228589098 100644 --- a/go/cmd/vtctldclient/command/routing_rules.go +++ b/go/cmd/vtctldclient/command/routing_rules.go @@ -82,7 +82,7 @@ func commandApplyRoutingRules(cmd *cobra.Command, args []string) error { } rr := &vschemapb.RoutingRules{} - if err := json2.Unmarshal(rulesBytes, &rr); err != nil { + if err := json2.UnmarshalPB(rulesBytes, rr); err != nil { return err } diff --git a/go/cmd/vtctldclient/command/shard_routing_rules.go b/go/cmd/vtctldclient/command/shard_routing_rules.go index 10ce7e81747..2214269d0f3 100644 --- a/go/cmd/vtctldclient/command/shard_routing_rules.go +++ b/go/cmd/vtctldclient/command/shard_routing_rules.go @@ -87,7 +87,7 @@ func commandApplyShardRoutingRules(cmd *cobra.Command, args []string) error { } srr := &vschemapb.ShardRoutingRules{} - if err := json2.Unmarshal(rulesBytes, &srr); err != nil { + if err := json2.UnmarshalPB(rulesBytes, srr); err != nil { return err } // Round-trip so when we display the result it's readable. diff --git a/go/json2/unmarshal.go b/go/json2/unmarshal.go index e382b8ad47a..e2034fa71c9 100644 --- a/go/json2/unmarshal.go +++ b/go/json2/unmarshal.go @@ -33,8 +33,7 @@ var carriageReturn = []byte("\n") // efficient and should not be used for high QPS operations. func Unmarshal(data []byte, v any) error { if pb, ok := v.(proto.Message); ok { - opts := protojson.UnmarshalOptions{DiscardUnknown: true} - return annotate(data, opts.Unmarshal(data, pb)) + return UnmarshalPB(data, pb) } return annotate(data, json.Unmarshal(data, v)) } @@ -53,3 +52,9 @@ func annotate(data []byte, err error) error { return fmt.Errorf("line: %d, position %d: %v", line, pos, err) } + +// UnmarshalPB is similar to Unmarshal but specifically for proto.Message to add type safety. +func UnmarshalPB(data []byte, pb proto.Message) error { + opts := protojson.UnmarshalOptions{DiscardUnknown: true} + return annotate(data, opts.Unmarshal(data, pb)) +} diff --git a/go/json2/unmarshal_test.go b/go/json2/unmarshal_test.go index ff18a29def8..1ba3368d5ca 100644 --- a/go/json2/unmarshal_test.go +++ b/go/json2/unmarshal_test.go @@ -91,3 +91,14 @@ func TestAnnotate(t *testing.T) { require.Equal(t, tcase.err, err, "annotate(%s, %v) error", string(tcase.data), tcase.err) } } + +func TestUnmarshalPB(t *testing.T) { + want := &emptypb.Empty{} + json, err := protojson.Marshal(want) + require.NoError(t, err) + + var got emptypb.Empty + err = UnmarshalPB(json, &got) + require.NoError(t, err) + require.Equal(t, want, &got) +} diff --git a/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go b/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go index bca51512a3c..4a3f16a1cc9 100644 --- a/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go +++ b/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go @@ -19,6 +19,7 @@ package vreplication import ( "encoding/json" "fmt" + "os" "slices" "strings" "testing" @@ -27,6 +28,7 @@ import ( "golang.org/x/exp/maps" "google.golang.org/protobuf/encoding/protojson" + "vitess.io/vitess/go/json2" "vitess.io/vitess/go/test/endtoend/cluster" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" @@ -61,6 +63,9 @@ func TestVtctldclientCLI(t *testing.T) { workflowName := "wf1" targetTabs := setupMinimalCustomerKeyspace(t) + t.Run("RoutingRulesApply", func(t *testing.T) { + testRoutingRulesApplyCommands(t) + }) t.Run("WorkflowList", func(t *testing.T) { testWorkflowList(t, sourceKeyspaceName, targetKeyspaceName) }) @@ -438,3 +443,138 @@ func validateMoveTablesWorkflow(t *testing.T, workflows []*vtctldatapb.Workflow) require.Equal(t, binlogdatapb.OnDDLAction_STOP, bls.OnDdl) require.True(t, bls.StopAfterCopy) } + +// Test that routing rules can be applied using the vtctldclient CLI for all types of routing rules. +func testRoutingRulesApplyCommands(t *testing.T) { + var rulesBytes []byte + var err error + var validateRules func(want, got string) + + ruleTypes := []string{"RoutingRules", "ShardRoutingRules", "KeyspaceRoutingRules"} + for _, typ := range ruleTypes { + switch typ { + case "RoutingRules": + rr := &vschemapb.RoutingRules{ + Rules: []*vschemapb.RoutingRule{ + { + FromTable: "from1", + ToTables: []string{"to1", "to2"}, + }, + }, + } + rulesBytes, err = json2.MarshalPB(rr) + require.NoError(t, err) + validateRules = func(want, got string) { + var wantRules = &vschemapb.RoutingRules{} + require.NoError(t, json2.UnmarshalPB([]byte(want), wantRules)) + var gotRules = &vschemapb.RoutingRules{} + require.NoError(t, json2.UnmarshalPB([]byte(got), gotRules)) + require.EqualValues(t, wantRules, gotRules) + } + case "ShardRoutingRules": + srr := &vschemapb.ShardRoutingRules{ + Rules: []*vschemapb.ShardRoutingRule{ + { + FromKeyspace: "from1", + ToKeyspace: "to1", + Shard: "-80", + }, + }, + } + rulesBytes, err = json2.MarshalPB(srr) + require.NoError(t, err) + validateRules = func(want, got string) { + var wantRules = &vschemapb.ShardRoutingRules{} + require.NoError(t, json2.UnmarshalPB([]byte(want), wantRules)) + var gotRules = &vschemapb.ShardRoutingRules{} + require.NoError(t, json2.UnmarshalPB([]byte(got), gotRules)) + require.EqualValues(t, wantRules, gotRules) + } + case "KeyspaceRoutingRules": + krr := &vschemapb.KeyspaceRoutingRules{ + Rules: []*vschemapb.KeyspaceRoutingRule{ + { + FromKeyspace: "from1", + ToKeyspace: "to1", + }, + }, + } + rulesBytes, err = json2.MarshalPB(krr) + require.NoError(t, err) + validateRules = func(want, got string) { + var wantRules = &vschemapb.KeyspaceRoutingRules{} + require.NoError(t, json2.UnmarshalPB([]byte(want), wantRules)) + var gotRules = &vschemapb.KeyspaceRoutingRules{} + require.NoError(t, json2.UnmarshalPB([]byte(got), gotRules)) + require.EqualValues(t, wantRules, gotRules) + } + default: + require.FailNow(t, "Unknown type %s", typ) + } + testOneRoutingRulesCommand(t, typ, string(rulesBytes), validateRules) + } + +} + +// For a given routing rules type, test that the rules can be applied using the vtctldclient CLI. +// We test both inline and file-based rules. +// The test also validates that both camelCase and snake_case key names work correctly. +func testOneRoutingRulesCommand(t *testing.T, typ string, rules string, validateRules func(want, got string)) { + type routingRulesTest struct { + name string + rules string + useFile bool // if true, use a file to pass the rules + } + tests := []routingRulesTest{ + { + name: "inline", + rules: rules, + }, + { + name: "file", + rules: rules, + useFile: true, + }, + { + name: "empty", // finally, cleanup rules + rules: "{}", + }, + } + for _, tt := range tests { + t.Run(typ+"/"+tt.name, func(t *testing.T) { + wantRules := tt.rules + // The input rules are in camelCase, since they are the output of json2.MarshalPB + // The first iteration uses the output of routing rule Gets which are in snake_case. + for _, keyCase := range []string{"camelCase", "snake_case"} { + t.Run(keyCase, func(t *testing.T) { + var args []string + apply := fmt.Sprintf("Apply%s", typ) + get := fmt.Sprintf("Get%s", typ) + args = append(args, apply) + if tt.useFile { + tmpFile, err := os.CreateTemp("", fmt.Sprintf("%s_rules.json", tt.name)) + require.NoError(t, err) + defer os.Remove(tmpFile.Name()) + _, err = tmpFile.WriteString(wantRules) + require.NoError(t, err) + args = append(args, "--rules-file", tmpFile.Name()) + } else { + args = append(args, "--rules", wantRules) + } + var output string + var err error + if output, err = vc.VtctldClient.ExecuteCommandWithOutput(args...); err != nil { + require.FailNowf(t, "failed action", apply, "%v: %s", err, output) + } + if output, err = vc.VtctldClient.ExecuteCommandWithOutput(get); err != nil { + require.FailNowf(t, "failed action", get, "%v: %s", err, output) + } + validateRules(wantRules, output) + // output of GetRoutingRules is in snake_case and we use it for the next iteration which + // tests applying rules with snake_case keys. + wantRules = output + }) + } + }) + } +} From 6d8bb744f469ab5b31e577ce2372ac1ff509de69 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Wed, 12 Jun 2024 11:09:03 -0400 Subject: [PATCH 23/40] VReplication: Improve workflow cancel/delete (#15977) Signed-off-by: Matt Lord --- go/test/endtoend/cluster/vttablet_process.go | 10 +- go/test/endtoend/vreplication/helper_test.go | 39 +- .../vreplication/vreplication_test.go | 51 +- .../vreplication/vreplication_test_env.go | 23 +- go/vt/topo/shard.go | 35 +- go/vt/topo/shard_test.go | 9 +- go/vt/vtctl/workflow/framework_test.go | 458 ++++++++++++++ go/vt/vtctl/workflow/materializer_env_test.go | 16 +- go/vt/vtctl/workflow/server.go | 145 +++-- go/vt/vtctl/workflow/server_test.go | 581 ++++++++++++++++++ go/vt/vtctl/workflow/switcher_dry_run.go | 148 ++++- go/vt/vtctl/workflow/traffic_switcher.go | 157 +++-- .../tabletmanager/rpc_vreplication_test.go | 7 + 13 files changed, 1452 insertions(+), 227 deletions(-) create mode 100644 go/vt/vtctl/workflow/framework_test.go diff --git a/go/test/endtoend/cluster/vttablet_process.go b/go/test/endtoend/cluster/vttablet_process.go index 45db1dc4bd2..6bd60b63191 100644 --- a/go/test/endtoend/cluster/vttablet_process.go +++ b/go/test/endtoend/cluster/vttablet_process.go @@ -74,6 +74,7 @@ type VttabletProcess struct { SupportsBackup bool ExplicitServingStatus bool ServingStatus string + DbName string DbPassword string DbPort int DbFlavor string @@ -148,6 +149,8 @@ func (vttablet *VttabletProcess) Setup() (err error) { return } + vttablet.DbName = "vt_" + vttablet.Keyspace + vttablet.exit = make(chan error) go func() { if vttablet.proc != nil { @@ -442,8 +445,11 @@ func (vttablet *VttabletProcess) TearDownWithTimeout(timeout time.Duration) erro // CreateDB creates the database for keyspace func (vttablet *VttabletProcess) CreateDB(keyspace string) error { - _, _ = vttablet.QueryTablet(fmt.Sprintf("drop database IF EXISTS vt_%s", keyspace), keyspace, false) - _, err := vttablet.QueryTablet(fmt.Sprintf("create database IF NOT EXISTS vt_%s", keyspace), keyspace, false) + if vttablet.DbName == "" { + vttablet.DbName = "vt_" + keyspace + } + _, _ = vttablet.QueryTablet(fmt.Sprintf("drop database IF EXISTS %s", vttablet.DbName), keyspace, false) + _, err := vttablet.QueryTablet(fmt.Sprintf("create database IF NOT EXISTS %s", vttablet.DbName), keyspace, false) return err } diff --git a/go/test/endtoend/vreplication/helper_test.go b/go/test/endtoend/vreplication/helper_test.go index 4764b213ad6..eca4c312ae7 100644 --- a/go/test/endtoend/vreplication/helper_test.go +++ b/go/test/endtoend/vreplication/helper_test.go @@ -92,7 +92,7 @@ func execQueryWithRetry(t *testing.T, conn *mysql.Conn, query string, timeout ti select { case <-ctx.Done(): require.FailNow(t, fmt.Sprintf("query %q did not succeed before the timeout of %s; last seen result: %v", - query, timeout, qr.Rows)) + query, timeout, qr)) case <-ticker.C: log.Infof("query %q failed with error %v, retrying in %ds", query, err, defaultTick) } @@ -147,19 +147,6 @@ func execVtgateQuery(t *testing.T, conn *mysql.Conn, database string, query stri return qr } -func execVtgateQueryWithRetry(t *testing.T, conn *mysql.Conn, database string, query string, timeout time.Duration) *sqltypes.Result { - if strings.TrimSpace(query) == "" { - return nil - } - if database != "" { - execQuery(t, conn, "use `"+database+"`;") - } - execQuery(t, conn, "begin") - qr := execQueryWithRetry(t, conn, query, timeout) - execQuery(t, conn, "commit") - return qr -} - func checkHealth(t *testing.T, url string) bool { resp, err := http.Get(url) require.NoError(t, err) @@ -516,20 +503,24 @@ func validateDryRunResults(t *testing.T, output string, want []string) { require.NotEmpty(t, output) gotDryRun := strings.Split(output, "\n") require.True(t, len(gotDryRun) > 3) - startRow := 3 - if strings.Contains(gotDryRun[0], "deprecated") { + var startRow int + if strings.HasPrefix(gotDryRun[1], "Parameters:") { // vtctlclient + startRow = 3 + } else if strings.Contains(gotDryRun[0], "deprecated") { startRow = 4 + } else { + startRow = 2 } gotDryRun = gotDryRun[startRow : len(gotDryRun)-1] if len(want) != len(gotDryRun) { - t.Fatalf("want and got: lengths don't match, \nwant\n%s\n\ngot\n%s", strings.Join(want, "\n"), strings.Join(gotDryRun, "\n")) + require.Fail(t, "invalid dry run results", "want and got: lengths don't match, \nwant\n%s\n\ngot\n%s", strings.Join(want, "\n"), strings.Join(gotDryRun, "\n")) } var match, fail bool fail = false for i, w := range want { w = strings.TrimSpace(w) g := strings.TrimSpace(gotDryRun[i]) - if w[0] == '/' { + if len(w) > 0 && w[0] == '/' { w = strings.TrimSpace(w[1:]) result := strings.HasPrefix(g, w) match = result @@ -538,11 +529,11 @@ func validateDryRunResults(t *testing.T, output string, want []string) { } if !match { fail = true - t.Fatalf("want %s, got %s\n", w, gotDryRun[i]) + require.Fail(t, "invlaid dry run results", "want %s, got %s\n", w, gotDryRun[i]) } } if fail { - t.Fatalf("Dry run results don't match, want %s, got %s", want, gotDryRun) + require.Fail(t, "invalid dry run results", "Dry run results don't match, want %s, got %s", want, gotDryRun) } } @@ -578,7 +569,7 @@ func isTableInDenyList(t *testing.T, vc *VitessCluster, ksShard string, table st var err error found := false if output, err = vc.VtctlClient.ExecuteCommandWithOutput("GetShard", ksShard); err != nil { - t.Fatalf("%v %v", err, output) + require.Fail(t, "GetShard error", "%v %v", err, output) return false, err } jsonparser.ArrayEach([]byte(output), func(value []byte, dataType jsonparser.ValueType, offset int, err error) { @@ -602,8 +593,8 @@ func expectNumberOfStreams(t *testing.T, vtgateConn *mysql.Conn, name string, wo waitForQueryResult(t, vtgateConn, database, query, fmt.Sprintf(`[[INT64(%d)]]`, want)) } -// confirmAllStreamsRunning confirms that all of the migrated streams are running -// after a Reshard. +// confirmAllStreamsRunning confirms that all of the workflow's streams are +// in the running state. func confirmAllStreamsRunning(t *testing.T, vtgateConn *mysql.Conn, database string) { query := sqlparser.BuildParsedQuery("select count(*) from %s.vreplication where state != '%s'", sidecarDBIdentifier, binlogdatapb.VReplicationWorkflowState_Running.String()).Query @@ -801,7 +792,7 @@ func isBinlogRowImageNoBlob(t *testing.T, tablet *cluster.VttabletProcess) bool func getRowCount(t *testing.T, vtgateConn *mysql.Conn, table string) int { query := fmt.Sprintf("select count(*) from %s", table) - qr := execVtgateQuery(t, vtgateConn, "", query) + qr := execQuery(t, vtgateConn, query) numRows, _ := qr.Rows[0][0].ToInt() return numRows } diff --git a/go/test/endtoend/vreplication/vreplication_test.go b/go/test/endtoend/vreplication/vreplication_test.go index c06489006f8..db58f2880c2 100644 --- a/go/test/endtoend/vreplication/vreplication_test.go +++ b/go/test/endtoend/vreplication/vreplication_test.go @@ -367,6 +367,7 @@ func testVreplicationWorkflows(t *testing.T, limited bool, binlogRowImage string expectNumberOfStreams(t, vtgateConn, "Customer3to2", "sales", "product:0", 3) reshardCustomer3to1Merge(t) confirmAllStreamsRunning(t, vtgateConn, "customer:0") + expectNumberOfStreams(t, vtgateConn, "Customer3to1", "sales", "product:0", 1) t.Run("Verify CopyState Is Optimized Afterwards", func(t *testing.T) { @@ -605,7 +606,7 @@ func TestCellAliasVreplicationWorkflow(t *testing.T) { vc.AddKeyspace(t, []*Cell{cell1, cell2}, keyspace, shard, initialProductVSchema, initialProductSchema, defaultReplicas, defaultRdonly, 100, sourceKsOpts) // Add cell alias containing only zone2 - result, err := vc.VtctlClient.ExecuteCommandWithOutput("AddCellsAlias", "--", "--cells", "zone2", "alias") + result, err := vc.VtctldClient.ExecuteCommandWithOutput("AddCellsAlias", "--cells", "zone2", "alias") require.NoError(t, err, "command failed with output: %v", result) verifyClusterHealth(t, vc) @@ -722,10 +723,13 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl execVtgateQuery(t, vtgateConn, sourceKs, "update json_tbl set j1 = null, j2 = 'null', j3 = '\"null\"'") execVtgateQuery(t, vtgateConn, sourceKs, "insert into json_tbl(id, j1, j2, j3) values (7, null, 'null', '\"null\"')") waitForNoWorkflowLag(t, vc, targetKs, workflow) - for _, shard := range []string{"-80", "80-"} { - shardTarget := fmt.Sprintf("%s:%s", targetKs, shard) - if res := execVtgateQuery(t, vtgateConn, shardTarget, "select cid from customer"); len(res.Rows) > 0 { - waitForQueryResult(t, vtgateConn, shardTarget, "select distinct dec80 from customer", `[[DECIMAL(0)]]`) + for _, tablet := range []*cluster.VttabletProcess{customerTab1, customerTab2} { + // Query the tablet's mysqld directly as the targets will have denied table entries. + dbc, err := tablet.TabletConn(targetKs, true) + require.NoError(t, err) + defer dbc.Close() + if res := execQuery(t, dbc, "select cid from customer"); len(res.Rows) > 0 { + waitForQueryResult(t, dbc, tablet.DbName, "select distinct dec80 from customer", `[[DECIMAL(0)]]`) dec80Replicated = true } } @@ -833,7 +837,7 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl printShardPositions(vc, ksShards) switchWrites(t, workflowType, ksWorkflow, true) - output, err := vc.VtctlClient.ExecuteCommandWithOutput("Workflow", ksWorkflow, "show") + output, err := vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", targetKs, "show", "--workflow", workflow) require.NoError(t, err) require.Contains(t, output, "'customer.reverse_bits'") require.Contains(t, output, "'customer.bmd5'") @@ -942,7 +946,7 @@ func reshardMerchant2to3SplitMerge(t *testing.T) { var err error for _, shard := range strings.Split("-80,80-", ",") { - output, err = vc.VtctlClient.ExecuteCommandWithOutput("GetShard", "merchant:"+shard) + output, err = vc.VtctldClient.ExecuteCommandWithOutput("GetShard", "merchant:"+shard) if err == nil { t.Fatal("GetShard merchant:-80 failed") } @@ -951,7 +955,7 @@ func reshardMerchant2to3SplitMerge(t *testing.T) { for _, shard := range strings.Split("-40,40-c0,c0-", ",") { ksShard := fmt.Sprintf("%s:%s", merchantKeyspace, shard) - output, err = vc.VtctlClient.ExecuteCommandWithOutput("GetShard", ksShard) + output, err = vc.VtctldClient.ExecuteCommandWithOutput("GetShard", ksShard) if err != nil { t.Fatalf("GetShard merchant failed for: %s: %v", shard, err) } @@ -1400,7 +1404,7 @@ func waitForLowLag(t *testing.T, keyspace, workflow string) { waitDuration := 500 * time.Millisecond duration := maxWait for duration > 0 { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("Workflow", fmt.Sprintf("%s.%s", keyspace, workflow), "Show") + output, err := vc.VtctldClient.ExecuteCommandWithOutput("Workflow", "--keyspace", "show", "--workflow", workflow) require.NoError(t, err) lagSeconds, err = jsonparser.GetInt([]byte(output), "MaxVReplicationTransactionLag") @@ -1483,7 +1487,7 @@ func reshardAction(t *testing.T, action, workflow, keyspaceName, sourceShards, t } func applyVSchema(t *testing.T, vschema, keyspace string) { - err := vc.VtctlClient.ExecuteCommand("ApplyVSchema", "--", "--vschema", vschema, keyspace) + err := vc.VtctldClient.ExecuteCommand("ApplyVSchema", "--vschema", vschema, keyspace) require.NoError(t, err) } @@ -1494,8 +1498,10 @@ func switchReadsDryRun(t *testing.T, workflowType, cells, ksWorkflow string, dry "workflow type specified: %s", workflowType) } ensureCanSwitch(t, workflowType, cells, ksWorkflow) - output, err := vc.VtctlClient.ExecuteCommandWithOutput(workflowType, "--", "--cells="+cells, "--tablet_types=rdonly,replica", - "--dry_run", "SwitchTraffic", ksWorkflow) + ks, wf, ok := strings.Cut(ksWorkflow, ".") + require.True(t, ok) + output, err := vc.VtctldClient.ExecuteCommandWithOutput(workflowType, "--workflow", wf, "--target-keyspace", ks, "SwitchTraffic", + "--cells="+cells, "--tablet-types=rdonly,replica", "--dry-run") require.NoError(t, err, fmt.Sprintf("Switching Reads DryRun Error: %s: %s", err, output)) if dryRunResults != nil { validateDryRunResults(t, output, dryRunResults) @@ -1503,10 +1509,13 @@ func switchReadsDryRun(t *testing.T, workflowType, cells, ksWorkflow string, dry } func ensureCanSwitch(t *testing.T, workflowType, cells, ksWorkflow string) { + ks, wf, ok := strings.Cut(ksWorkflow, ".") + require.True(t, ok) timer := time.NewTimer(defaultTimeout) defer timer.Stop() for { - _, err := vc.VtctlClient.ExecuteCommandWithOutput(workflowType, "--", "--cells="+cells, "--dry_run", "SwitchTraffic", ksWorkflow) + _, err := vc.VtctldClient.ExecuteCommandWithOutput(workflowType, "--workflow", wf, "--target-keyspace", ks, "SwitchTraffic", + "--cells="+cells, "--dry-run") if err == nil { return } @@ -1532,11 +1541,13 @@ func switchReads(t *testing.T, workflowType, cells, ksWorkflow string, reverse b command = "ReverseTraffic" } ensureCanSwitch(t, workflowType, cells, ksWorkflow) - output, err = vc.VtctlClient.ExecuteCommandWithOutput(workflowType, "--", "--cells="+cells, "--tablet_types=rdonly", - command, ksWorkflow) + ks, wf, ok := strings.Cut(ksWorkflow, ".") + require.True(t, ok) + output, err = vc.VtctldClient.ExecuteCommandWithOutput(workflowType, "--workflow", wf, "--target-keyspace", ks, command, + "--cells="+cells, "--tablet-types=rdonly") require.NoError(t, err, fmt.Sprintf("%s Error: %s: %s", command, err, output)) - output, err = vc.VtctlClient.ExecuteCommandWithOutput(workflowType, "--", "--cells="+cells, "--tablet_types=replica", - command, ksWorkflow) + output, err = vc.VtctldClient.ExecuteCommandWithOutput(workflowType, "--workflow", wf, "--target-keyspace", ks, command, + "--cells="+cells, "--tablet-types=replica") require.NoError(t, err, fmt.Sprintf("%s Error: %s: %s", command, err, output)) } @@ -1575,8 +1586,10 @@ func switchWritesDryRun(t *testing.T, workflowType, ksWorkflow string, dryRunRes require.FailNowf(t, "Invalid workflow type for SwitchTraffic, must be MoveTables or Reshard", "workflow type specified: %s", workflowType) } - output, err := vc.VtctlClient.ExecuteCommandWithOutput(workflowType, "--", "--tablet_types=primary", "--dry_run", - "SwitchTraffic", ksWorkflow) + ks, wf, ok := strings.Cut(ksWorkflow, ".") + require.True(t, ok) + output, err := vc.VtctldClient.ExecuteCommandWithOutput(workflowType, "--workflow", wf, "--target-keyspace", ks, + "SwitchTraffic", "--tablet-types=primary", "--dry-run") require.NoError(t, err, fmt.Sprintf("Switch writes DryRun Error: %s: %s", err, output)) validateDryRunResults(t, output, dryRunResults) } diff --git a/go/test/endtoend/vreplication/vreplication_test_env.go b/go/test/endtoend/vreplication/vreplication_test_env.go index 4500a98868c..6073cfac6ab 100644 --- a/go/test/endtoend/vreplication/vreplication_test_env.go +++ b/go/test/endtoend/vreplication/vreplication_test_env.go @@ -19,31 +19,28 @@ package vreplication var dryRunResultsSwitchWritesCustomerShard = []string{ "Lock keyspace product", "Lock keyspace customer", - "Stop writes on keyspace product, tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order]:", - "/ Keyspace product, Shard 0 at Position", - "Wait for VReplication on stopped streams to catchup for up to 30s", - "Create reverse replication workflow p2c_reverse", + "/Stop writes on keyspace product for tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order]: [keyspace:product;shard:0;position:", + "Wait for vreplication on stopped streams to catchup for up to 30s", + "Create reverse vreplication workflow p2c_reverse", "Create journal entries on source databases", - "Enable writes on keyspace customer tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order]", + "Enable writes on keyspace customer for tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order]", "Switch routing from keyspace product to keyspace customer", "Routing rules for tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order] will be updated", - "Switch writes completed, freeze and delete vreplication streams on:", - " tablet 200 ", - " tablet 300 ", - "Start reverse replication streams on:", - " tablet 100 ", - "Mark vreplication streams frozen on:", - " Keyspace customer, Shard -80, Tablet 200, Workflow p2c, DbName vt_customer", - " Keyspace customer, Shard 80-, Tablet 300, Workflow p2c, DbName vt_customer", + "Switch writes completed, freeze and delete vreplication streams on: [tablet:200,tablet:300]", + "Start reverse vreplication streams on: [tablet:100]", + "Mark vreplication streams frozen on: [keyspace:customer;shard:-80;tablet:200;workflow:p2c;dbname:vt_customer,keyspace:customer;shard:80-;tablet:300;workflow:p2c;dbname:vt_customer]", "Unlock keyspace customer", "Unlock keyspace product", + "", // Additional empty newline in the output } var dryRunResultsReadCustomerShard = []string{ "Lock keyspace product", "Switch reads for tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order] to keyspace customer for tablet types [RDONLY,REPLICA]", "Routing rules for tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order] will be updated", + "Serving VSchema will be rebuilt for the customer keyspace", "Unlock keyspace product", + "", // Additional empty newline in the output } var dryRunResultsSwitchWritesM2m3 = []string{ diff --git a/go/vt/topo/shard.go b/go/vt/topo/shard.go index b9554bf789f..77983f20d2d 100644 --- a/go/vt/topo/shard.go +++ b/go/vt/topo/shard.go @@ -21,7 +21,7 @@ import ( "encoding/hex" "fmt" "path" - "reflect" + "slices" "sort" "strings" "sync" @@ -44,8 +44,8 @@ import ( ) const ( - dlTablesAlreadyPresent = "one or more tables are already present in the denylist" - dlTablesNotPresent = "cannot remove tables since one or more do not exist in the denylist" + dlTablesAlreadyPresent = "one or more tables were already present in the denylist" + dlTablesNotPresent = "one or more tables did not exist in the denylist" dlNoCellsForPrimary = "you cannot specify cells for a primary's tablet control" ) @@ -397,16 +397,15 @@ func (si *ShardInfo) UpdateDeniedTables(ctx context.Context, tabletType topodata } tc := si.GetTabletControl(tabletType) if tc == nil { - - // handle the case where the TabletControl object is new + // Handle the case where the TabletControl object is new. if remove { - // we try to remove from something that doesn't exist, - // log, but we're done. + // We tried to remove something that doesn't exist, log a warning. + // But we know that our work is done. log.Warningf("Trying to remove TabletControl.DeniedTables for missing type %v in shard %v/%v", tabletType, si.keyspace, si.shardName) return nil } - // trying to add more constraints with no existing record + // Add constraints to the new record. si.TabletControls = append(si.TabletControls, &topodatapb.Shard_TabletControl{ TabletType: tabletType, Cells: cells, @@ -422,16 +421,16 @@ func (si *ShardInfo) UpdateDeniedTables(ctx context.Context, tabletType topodata return nil } - // we have an existing record, check table lists matches and + // We have an existing record, update the table lists. if remove { si.removeCellsFromTabletControl(tc, tabletType, cells) } else { - if !reflect.DeepEqual(tc.DeniedTables, tables) { + if !slices.Equal(tc.DeniedTables, tables) { return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "trying to use two different sets of denied tables for shard %v/%v: %v and %v", si.keyspace, si.shardName, tc.DeniedTables, tables) } - tc.Cells = addCells(tc.Cells, cells) } + return nil } @@ -451,7 +450,8 @@ func (si *ShardInfo) updatePrimaryTabletControl(tc *topodatapb.Shard_TabletContr } if remove { if len(newTables) != 0 { - return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, dlTablesNotPresent) + // These tables did not exist in the denied list so we don't need to remove them. + log.Warningf("%s:%s", dlTablesNotPresent, strings.Join(newTables, ",")) } var newDenyList []string if len(tables) != 0 { // legacy uses @@ -475,7 +475,16 @@ func (si *ShardInfo) updatePrimaryTabletControl(tc *topodatapb.Shard_TabletContr return nil } if len(newTables) != len(tables) { - return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, dlTablesAlreadyPresent) + // Some of the tables already existed in the DeniedTables list so we don't + // need to add them. + log.Warningf("%s:%s", dlTablesAlreadyPresent, strings.Join(tables, ",")) + // We do need to merge the lists, however. + tables = append(tables, newTables...) + tc.DeniedTables = append(tc.DeniedTables, tables...) + // And be sure to remove any duplicates. + slices.Sort(tc.DeniedTables) + tc.DeniedTables = slices.Compact(tc.DeniedTables) + return nil } tc.DeniedTables = append(tc.DeniedTables, tables...) return nil diff --git a/go/vt/topo/shard_test.go b/go/vt/topo/shard_test.go index 9afc8d0ea78..5e30a8aad2a 100644 --- a/go/vt/topo/shard_test.go +++ b/go/vt/topo/shard_test.go @@ -25,6 +25,7 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/test/utils" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) @@ -121,14 +122,14 @@ func TestUpdateSourcePrimaryDeniedTables(t *testing.T) { require.NoError(t, addToDenyList(ctx, si, primary, nil, tables2)) validateDenyList(t, si, primary, nil, append(tables1, tables2...)) - require.Error(t, addToDenyList(ctx, si, primary, nil, tables2), dlTablesAlreadyPresent) - require.Error(t, addToDenyList(ctx, si, primary, nil, []string{t1}), dlTablesAlreadyPresent) + require.NoError(t, addToDenyList(ctx, si, primary, nil, tables2)) + require.NoError(t, addToDenyList(ctx, si, primary, nil, []string{t1})) require.NoError(t, removeFromDenyList(ctx, si, primary, nil, tables2)) validateDenyList(t, si, primary, nil, tables1) - require.Error(t, removeFromDenyList(ctx, si, primary, nil, tables2), dlTablesNotPresent) - require.Error(t, removeFromDenyList(ctx, si, primary, nil, []string{t3}), dlTablesNotPresent) + require.NoError(t, removeFromDenyList(ctx, si, primary, nil, tables2)) + require.NoError(t, removeFromDenyList(ctx, si, primary, nil, []string{t3})) validateDenyList(t, si, primary, nil, tables1) require.NoError(t, removeFromDenyList(ctx, si, primary, nil, []string{t1})) diff --git a/go/vt/vtctl/workflow/framework_test.go b/go/vt/vtctl/workflow/framework_test.go new file mode 100644 index 00000000000..73b34015338 --- /dev/null +++ b/go/vt/vtctl/workflow/framework_test.go @@ -0,0 +1,458 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package workflow + +import ( + "context" + "fmt" + "os" + "regexp" + "strings" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" + "google.golang.org/protobuf/proto" + + "vitess.io/vitess/go/protoutil" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/mysqlctl/tmutils" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/topotools" + "vitess.io/vitess/go/vt/vtenv" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vttablet/tmclient" + + _flag "vitess.io/vitess/go/internal/flag" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" +) + +const ( + defaultCellName = "cell" + startingSourceTabletUID = 100 + startingTargetTabletUID = 200 + tabletUIDStep = 10 +) + +type testKeyspace struct { + KeyspaceName string + ShardNames []string +} + +type queryResult struct { + query string + result *querypb.QueryResult +} + +func TestMain(m *testing.M) { + _flag.ParseFlagsForTest() + os.Exit(m.Run()) +} + +type testEnv struct { + ws *Server + ts *topo.Server + tmc *testTMClient + sourceKeyspace, targetKeyspace *testKeyspace + // Keyed first by keyspace name, then tablet UID. + tablets map[string]map[int]*topodatapb.Tablet + cell string +} + +func newTestEnv(t *testing.T, ctx context.Context, cell string, sourceKeyspace, targetKeyspace *testKeyspace) *testEnv { + t.Helper() + env := &testEnv{ + ts: memorytopo.NewServer(ctx, cell), + sourceKeyspace: sourceKeyspace, + targetKeyspace: targetKeyspace, + tablets: make(map[string]map[int]*topodatapb.Tablet), + cell: cell, + } + venv := vtenv.NewTestEnv() + env.tmc = newTestTMClient(env) + env.ws = NewServer(venv, env.ts, env.tmc) + + tabletID := startingSourceTabletUID + for _, shardName := range sourceKeyspace.ShardNames { + _ = env.addTablet(t, ctx, tabletID, sourceKeyspace.KeyspaceName, shardName, topodatapb.TabletType_PRIMARY) + tabletID += tabletUIDStep + } + if sourceKeyspace.KeyspaceName != targetKeyspace.KeyspaceName { + tabletID = startingTargetTabletUID + for _, shardName := range targetKeyspace.ShardNames { + _ = env.addTablet(t, ctx, tabletID, targetKeyspace.KeyspaceName, shardName, topodatapb.TabletType_PRIMARY) + tabletID += tabletUIDStep + } + } + err := env.ts.RebuildSrvVSchema(ctx, nil) + require.NoError(t, err) + + return env +} + +func (env *testEnv) close() { + for _, k := range maps.Values(env.tablets) { + for _, t := range maps.Values(k) { + env.deleteTablet(t) + } + } +} + +func (env *testEnv) addTablet(t *testing.T, ctx context.Context, id int, keyspace, shard string, tabletType topodatapb.TabletType) *topodatapb.Tablet { + tablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: env.cell, + Uid: uint32(id), + }, + Keyspace: keyspace, + Shard: shard, + KeyRange: &topodatapb.KeyRange{}, + Type: tabletType, + PortMap: map[string]int32{ + "test": int32(id), + }, + } + if env.tablets[keyspace] == nil { + env.tablets[keyspace] = make(map[int]*topodatapb.Tablet) + } + env.tablets[keyspace][id] = tablet + err := env.ws.ts.InitTablet(ctx, tablet, false /* allowPrimaryOverride */, true /* createShardAndKeyspace */, false /* allowUpdate */) + require.NoError(t, err) + if tabletType == topodatapb.TabletType_PRIMARY { + _, err = env.ws.ts.UpdateShardFields(ctx, keyspace, shard, func(si *topo.ShardInfo) error { + si.PrimaryAlias = tablet.Alias + si.IsPrimaryServing = true + return nil + }) + require.NoError(t, err) + } + return tablet +} + +// addTableRoutingRules adds routing rules from the test env's source keyspace to +// its target keyspace for the given tablet types and tables. +func (env *testEnv) addTableRoutingRules(t *testing.T, ctx context.Context, tabletTypes []topodatapb.TabletType, tables []string) { + ks := env.targetKeyspace.KeyspaceName + rules := make(map[string][]string, len(tables)*(len(tabletTypes)*3)) + for _, tabletType := range tabletTypes { + for _, tableName := range tables { + toTarget := []string{ks + "." + tableName} + tt := strings.ToLower(tabletType.String()) + if tabletType == topodatapb.TabletType_PRIMARY { + rules[tableName] = toTarget + rules[ks+"."+tableName] = toTarget + rules[env.sourceKeyspace.KeyspaceName+"."+tableName] = toTarget + } else { + rules[tableName+"@"+tt] = toTarget + rules[ks+"."+tableName+"@"+tt] = toTarget + rules[env.sourceKeyspace.KeyspaceName+"."+tableName+"@"+tt] = toTarget + } + } + } + err := topotools.SaveRoutingRules(ctx, env.ts, rules) + require.NoError(t, err) + err = env.ts.RebuildSrvVSchema(ctx, nil) + require.NoError(t, err) +} + +func (env *testEnv) deleteTablet(tablet *topodatapb.Tablet) { + _ = env.ts.DeleteTablet(context.Background(), tablet.Alias) + delete(env.tablets[tablet.Keyspace], int(tablet.Alias.Uid)) +} + +type testTMClient struct { + tmclient.TabletManagerClient + schema map[string]*tabletmanagerdatapb.SchemaDefinition + + mu sync.Mutex + vrQueries map[int][]*queryResult + createVReplicationWorkflowRequests map[uint32]*tabletmanagerdatapb.CreateVReplicationWorkflowRequest + readVReplicationWorkflowRequests map[uint32]*tabletmanagerdatapb.ReadVReplicationWorkflowRequest + + env *testEnv // For access to the env config from tmc methods. + reverse atomic.Bool // Are we reversing traffic? +} + +func newTestTMClient(env *testEnv) *testTMClient { + return &testTMClient{ + schema: make(map[string]*tabletmanagerdatapb.SchemaDefinition), + vrQueries: make(map[int][]*queryResult), + createVReplicationWorkflowRequests: make(map[uint32]*tabletmanagerdatapb.CreateVReplicationWorkflowRequest), + readVReplicationWorkflowRequests: make(map[uint32]*tabletmanagerdatapb.ReadVReplicationWorkflowRequest), + env: env, + } +} + +func (tmc *testTMClient) CreateVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.CreateVReplicationWorkflowRequest) (*tabletmanagerdatapb.CreateVReplicationWorkflowResponse, error) { + tmc.mu.Lock() + defer tmc.mu.Unlock() + + if expect := tmc.createVReplicationWorkflowRequests[tablet.Alias.Uid]; expect != nil { + if !proto.Equal(expect, req) { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected CreateVReplicationWorkflow request: got %+v, want %+v", req, expect) + } + } + res := sqltypes.MakeTestResult(sqltypes.MakeTestFields("rowsaffected", "int64"), "1") + return &tabletmanagerdatapb.CreateVReplicationWorkflowResponse{Result: sqltypes.ResultToProto3(res)}, nil +} + +func (tmc *testTMClient) ReadVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.ReadVReplicationWorkflowRequest) (*tabletmanagerdatapb.ReadVReplicationWorkflowResponse, error) { + tmc.mu.Lock() + defer tmc.mu.Unlock() + + if expect := tmc.readVReplicationWorkflowRequests[tablet.Alias.Uid]; expect != nil { + if !proto.Equal(expect, req) { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected ReadVReplicationWorkflow request: got %+v, want %+v", req, expect) + } + } + workflowType := binlogdatapb.VReplicationWorkflowType_MoveTables + if strings.Contains(req.Workflow, "lookup") { + workflowType = binlogdatapb.VReplicationWorkflowType_CreateLookupIndex + } + res := &tabletmanagerdatapb.ReadVReplicationWorkflowResponse{ + Workflow: req.Workflow, + WorkflowType: workflowType, + Streams: make([]*tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream, 0, 2), + } + rules := make([]*binlogdatapb.Rule, len(tmc.schema)) + for i, table := range maps.Keys(tmc.schema) { + rules[i] = &binlogdatapb.Rule{ + Match: table, + Filter: fmt.Sprintf("select * from %s", table), + } + } + blsKs := tmc.env.sourceKeyspace + if tmc.reverse.Load() && tablet.Keyspace == tmc.env.sourceKeyspace.KeyspaceName { + blsKs = tmc.env.targetKeyspace + } + for i, shard := range blsKs.ShardNames { + stream := &tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream{ + Id: int32(i + 1), + Bls: &binlogdatapb.BinlogSource{ + Keyspace: blsKs.KeyspaceName, + Shard: shard, + Tables: maps.Keys(tmc.schema), + Filter: &binlogdatapb.Filter{ + Rules: rules, + }, + }, + } + res.Streams = append(res.Streams, stream) + } + + return res, nil +} + +func (tmc *testTMClient) DeleteVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.DeleteVReplicationWorkflowRequest) (response *tabletmanagerdatapb.DeleteVReplicationWorkflowResponse, err error) { + return &tabletmanagerdatapb.DeleteVReplicationWorkflowResponse{ + Result: &querypb.QueryResult{ + RowsAffected: 1, + }, + }, nil +} + +func (tmc *testTMClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.GetSchemaRequest) (*tabletmanagerdatapb.SchemaDefinition, error) { + tmc.mu.Lock() + defer tmc.mu.Unlock() + + schemaDefn := &tabletmanagerdatapb.SchemaDefinition{} + for _, table := range req.Tables { + if table == "/.*/" { + // Special case of all tables in keyspace. + for key, tableDefn := range tmc.schema { + if strings.HasPrefix(key, tablet.Keyspace+".") { + schemaDefn.TableDefinitions = append(schemaDefn.TableDefinitions, tableDefn.TableDefinitions...) + } + } + break + } + + key := tablet.Keyspace + "." + table + tableDefn := tmc.schema[key] + if tableDefn == nil { + continue + } + schemaDefn.TableDefinitions = append(schemaDefn.TableDefinitions, tableDefn.TableDefinitions...) + } + return schemaDefn, nil +} + +func (tmc *testTMClient) expectVRQuery(tabletID int, query string, result *sqltypes.Result) { + tmc.mu.Lock() + defer tmc.mu.Unlock() + + tmc.vrQueries[tabletID] = append(tmc.vrQueries[tabletID], &queryResult{ + query: query, + result: sqltypes.ResultToProto3(result), + }) +} + +func (tmc *testTMClient) expectVRQueryResultOnKeyspaceTablets(keyspace string, queryResult *queryResult) { + tmc.mu.Lock() + defer tmc.mu.Unlock() + + for uid := range tmc.env.tablets[keyspace] { + tmc.vrQueries[uid] = append(tmc.vrQueries[uid], queryResult) + } +} + +func (tmc *testTMClient) expectCreateVReplicationWorkflowRequest(tabletID uint32, req *tabletmanagerdatapb.CreateVReplicationWorkflowRequest) { + tmc.mu.Lock() + defer tmc.mu.Unlock() + + tmc.createVReplicationWorkflowRequests[tabletID] = req +} + +func (tmc *testTMClient) VReplicationExec(ctx context.Context, tablet *topodatapb.Tablet, query string) (*querypb.QueryResult, error) { + tmc.mu.Lock() + defer tmc.mu.Unlock() + + qrs := tmc.vrQueries[int(tablet.Alias.Uid)] + if len(qrs) == 0 { + return nil, fmt.Errorf("tablet %v does not expect any more queries: %s", tablet, query) + } + matched := false + if qrs[0].query[0] == '/' { + matched = regexp.MustCompile(qrs[0].query[1:]).MatchString(query) + } else { + matched = query == qrs[0].query + } + if !matched { + return nil, fmt.Errorf("tablet %v:\nunexpected query\n%s\nwant:\n%s", tablet, query, qrs[0].query) + } + tmc.vrQueries[int(tablet.Alias.Uid)] = qrs[1:] + return qrs[0].result, nil +} + +func (tmc *testTMClient) ExecuteFetchAsDba(ctx context.Context, tablet *topodatapb.Tablet, usePool bool, req *tabletmanagerdatapb.ExecuteFetchAsDbaRequest) (*querypb.QueryResult, error) { + // Reuse VReplicationExec. + return tmc.VReplicationExec(ctx, tablet, string(req.Query)) +} + +func (tmc *testTMClient) ExecuteFetchAsAllPrivs(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.ExecuteFetchAsAllPrivsRequest) (*querypb.QueryResult, error) { + return nil, nil +} + +// Note: ONLY breaks up change.SQL into individual statements and executes it. Does NOT fully implement ApplySchema. +func (tmc *testTMClient) ApplySchema(ctx context.Context, tablet *topodatapb.Tablet, change *tmutils.SchemaChange) (*tabletmanagerdatapb.SchemaChangeResult, error) { + stmts := strings.Split(change.SQL, ";") + + for _, stmt := range stmts { + _, err := tmc.ExecuteFetchAsDba(ctx, tablet, false, &tabletmanagerdatapb.ExecuteFetchAsDbaRequest{ + Query: []byte(stmt), + MaxRows: 0, + ReloadSchema: true, + }) + if err != nil { + return nil, err + } + } + + return nil, nil +} + +func (tmc *testTMClient) VDiff(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.VDiffRequest) (*tabletmanagerdatapb.VDiffResponse, error) { + return &tabletmanagerdatapb.VDiffResponse{ + Id: 1, + VdiffUuid: req.VdiffUuid, + Output: &querypb.QueryResult{ + RowsAffected: 1, + }, + }, nil +} + +func (tmc *testTMClient) HasVReplicationWorkflows(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.HasVReplicationWorkflowsRequest) (*tabletmanagerdatapb.HasVReplicationWorkflowsResponse, error) { + return &tabletmanagerdatapb.HasVReplicationWorkflowsResponse{ + Has: false, + }, nil +} + +func (tmc *testTMClient) ReadVReplicationWorkflows(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.ReadVReplicationWorkflowsRequest) (*tabletmanagerdatapb.ReadVReplicationWorkflowsResponse, error) { + tmc.mu.Lock() + defer tmc.mu.Unlock() + + workflowType := binlogdatapb.VReplicationWorkflowType_MoveTables + if len(req.IncludeWorkflows) > 0 { + for _, wf := range req.IncludeWorkflows { + if strings.Contains(wf, "lookup") { + workflowType = binlogdatapb.VReplicationWorkflowType_CreateLookupIndex + } + } + ks := tmc.env.sourceKeyspace + if tmc.reverse.Load() { + ks = tmc.env.targetKeyspace + } + return &tabletmanagerdatapb.ReadVReplicationWorkflowsResponse{ + Workflows: []*tabletmanagerdatapb.ReadVReplicationWorkflowResponse{ + { + Workflow: req.IncludeWorkflows[0], + WorkflowType: workflowType, + Streams: []*tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream{ + { + Id: 1, + State: binlogdatapb.VReplicationWorkflowState_Running, + Bls: &binlogdatapb.BinlogSource{ + Keyspace: ks.KeyspaceName, + Shard: ks.ShardNames[0], + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{ + { + Match: "/.*/", + }, + }, + }, + }, + Pos: "MySQL56/" + position, + TimeUpdated: protoutil.TimeToProto(time.Now()), + TimeHeartbeat: protoutil.TimeToProto(time.Now()), + }, + }, + }, + }, + }, nil + } else { + return &tabletmanagerdatapb.ReadVReplicationWorkflowsResponse{}, nil + } +} + +func (tmc *testTMClient) UpdateVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.UpdateVReplicationWorkflowRequest) (*tabletmanagerdatapb.UpdateVReplicationWorkflowResponse, error) { + return &tabletmanagerdatapb.UpdateVReplicationWorkflowResponse{ + Result: &querypb.QueryResult{ + RowsAffected: 1, + }, + }, nil +} + +func (tmc *testTMClient) PrimaryPosition(ctx context.Context, tablet *topodatapb.Tablet) (string, error) { + return position, nil +} + +func (tmc *testTMClient) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error { + return nil +} + +func (tmc *testTMClient) VReplicationWaitForPos(ctx context.Context, tablet *topodatapb.Tablet, id int32, pos string) error { + return nil +} diff --git a/go/vt/vtctl/workflow/materializer_env_test.go b/go/vt/vtctl/workflow/materializer_env_test.go index 587712f620c..fe49b24a10d 100644 --- a/go/vt/vtctl/workflow/materializer_env_test.go +++ b/go/vt/vtctl/workflow/materializer_env_test.go @@ -19,7 +19,6 @@ package workflow import ( "context" "fmt" - "os" "regexp" "strings" "sync" @@ -37,7 +36,6 @@ import ( "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tmclient" - _flag "vitess.io/vitess/go/internal/flag" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" @@ -46,11 +44,6 @@ import ( vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) -type queryResult struct { - query string - result *querypb.QueryResult -} - type testMaterializerEnv struct { ws *Server ms *vtctldatapb.MaterializeSettings @@ -65,11 +58,6 @@ type testMaterializerEnv struct { //---------------------------------------------- // testMaterializerEnv -func TestMain(m *testing.M) { - _flag.ParseFlagsForTest() - os.Exit(m.Run()) -} - func newTestMaterializerEnv(t *testing.T, ctx context.Context, ms *vtctldatapb.MaterializeSettings, sources, targets []string) *testMaterializerEnv { t.Helper() env := &testMaterializerEnv{ @@ -77,8 +65,8 @@ func newTestMaterializerEnv(t *testing.T, ctx context.Context, ms *vtctldatapb.M sources: sources, targets: targets, tablets: make(map[int]*topodatapb.Tablet), - topoServ: memorytopo.NewServer(ctx, "cell"), - cell: "cell", + topoServ: memorytopo.NewServer(ctx, defaultCellName), + cell: defaultCellName, tmc: newTestMaterializerTMClient(), } venv := vtenv.NewTestEnv() diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index 17b01736a77..587caff3c8c 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -22,7 +22,6 @@ import ( "errors" "fmt" "math" - "reflect" "slices" "sort" "strings" @@ -1452,13 +1451,31 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl return nil, err } + isStandardMoveTables := func() bool { + return !mz.IsMultiTenantMigration() && !mz.isPartial + } + + ts, err := s.buildTrafficSwitcher(ctx, req.GetTargetKeyspace(), req.GetWorkflow()) + if err != nil { + return nil, err + } + sw := &switcher{s: s, ts: ts} + lockCtx, targetUnlock, lockErr := sw.lockKeyspace(ctx, ts.TargetKeyspaceName(), "MoveTablesCreate") + if lockErr != nil { + ts.Logger().Errorf("Locking target keyspace %s failed: %v", ts.TargetKeyspaceName(), lockErr) + return nil, lockErr + } + defer targetUnlock(&err) + ctx = lockCtx + // If we get an error after this point, where the vreplication streams/records // have been created, then we clean up the workflow's artifacts. defer func() { if err != nil { - ts, cerr := s.buildTrafficSwitcher(ctx, ms.TargetKeyspace, ms.Workflow) - if cerr != nil { - err = vterrors.Wrapf(err, "failed to cleanup workflow artifacts: %v", cerr) + if isStandardMoveTables() { // Non-standard ones do not use shard scoped mechanisms + if cerr := ts.dropTargetDeniedTables(ctx); cerr != nil { + err = vterrors.Wrapf(err, "failed to cleanup denied table entries: %v", cerr) + } } if cerr := s.dropArtifacts(ctx, false, &switcher{s: s, ts: ts}); cerr != nil { err = vterrors.Wrapf(err, "failed to cleanup workflow artifacts: %v", cerr) @@ -1473,9 +1490,9 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl }() // Now that the streams have been successfully created, let's put the associated - // routing rules in place. + // routing rules and denied tables entries in place. if externalTopo == nil { - if err := s.setupInitialRoutingRules(ctx, req, mz, tables, vschema); err != nil { + if err := s.setupInitialRoutingRules(ctx, req, mz, tables); err != nil { return nil, err } @@ -1484,6 +1501,11 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl return nil, err } } + if isStandardMoveTables() { // Non-standard ones do not use shard scoped mechanisms + if err := s.setupInitialDeniedTables(ctx, ts); err != nil { + return nil, vterrors.Wrapf(err, "failed to put initial denied tables entries in place on the target shards") + } + } if err := s.ts.RebuildSrvVSchema(ctx, nil); err != nil { return nil, err } @@ -1547,7 +1569,24 @@ func (s *Server) validateRoutingRuleFlags(req *vtctldatapb.MoveTablesCreateReque return nil } -func (s *Server) setupInitialRoutingRules(ctx context.Context, req *vtctldatapb.MoveTablesCreateRequest, mz *materializer, tables []string, vschema *vschemapb.Keyspace) error { +func (s *Server) setupInitialDeniedTables(ctx context.Context, ts *trafficSwitcher) error { + if ts.MigrationType() != binlogdatapb.MigrationType_TABLES { + return nil + } + return ts.ForAllTargets(func(target *MigrationTarget) error { + if _, err := ts.TopoServer().UpdateShardFields(ctx, ts.TargetKeyspaceName(), target.GetShard().ShardName(), func(si *topo.ShardInfo) error { + return si.UpdateDeniedTables(ctx, topodatapb.TabletType_PRIMARY, nil, false, ts.Tables()) + }); err != nil { + return err + } + strCtx, cancel := context.WithTimeout(ctx, shardTabletRefreshTimeout) + defer cancel() + _, _, err := topotools.RefreshTabletsByShard(strCtx, ts.TopoServer(), ts.TabletManagerClient(), target.GetShard(), nil, ts.Logger()) + return err + }) +} + +func (s *Server) setupInitialRoutingRules(ctx context.Context, req *vtctldatapb.MoveTablesCreateRequest, mz *materializer, tables []string) error { if err := s.validateRoutingRuleFlags(req, mz); err != nil { return err } @@ -1616,7 +1655,7 @@ func (s *Server) MoveTablesComplete(ctx context.Context, req *vtctldatapb.MoveTa span, ctx := trace.NewSpan(ctx, "workflow.Server.MoveTablesComplete") defer span.Finish() - ts, state, err := s.getWorkflowState(ctx, req.TargetKeyspace, req.Workflow) + ts, state, err := s.getWorkflowState(ctx, req.GetTargetKeyspace(), req.GetWorkflow()) if err != nil { return nil, err } @@ -1630,8 +1669,7 @@ func (s *Server) MoveTablesComplete(ctx context.Context, req *vtctldatapb.MoveTa var dryRunResults *[]string if state.WorkflowType == TypeMigrate { - dryRunResults, err = s.finalizeMigrateWorkflow(ctx, req.TargetKeyspace, req.Workflow, strings.Join(ts.tables, ","), - false, req.KeepData, req.KeepRoutingRules, req.DryRun) + dryRunResults, err = s.finalizeMigrateWorkflow(ctx, ts, strings.Join(ts.tables, ","), false, req.KeepData, req.KeepRoutingRules, req.DryRun) if err != nil { return nil, vterrors.Wrapf(err, "failed to finalize the %s workflow in the %s keyspace", req.Workflow, req.TargetKeyspace) @@ -1970,11 +2008,21 @@ func (s *Server) WorkflowDelete(ctx context.Context, req *vtctldatapb.WorkflowDe span.Annotate("keep_routing_rules", req.KeepRoutingRules) span.Annotate("shards", req.Shards) - // Cleanup related data and artifacts. - if _, err := s.DropTargets(ctx, req.Keyspace, req.Workflow, req.KeepData, req.KeepRoutingRules, false); err != nil { - if topo.IsErrType(err, topo.NoNode) { - return nil, vterrors.Wrapf(err, "%s keyspace does not exist", req.Keyspace) + ts, state, err := s.getWorkflowState(ctx, req.GetKeyspace(), req.GetWorkflow()) + if err != nil { + log.Errorf("failed to get VReplication workflow state for %s.%s: %v", req.GetKeyspace(), req.GetWorkflow(), err) + return nil, err + } + + if ts.workflowType != binlogdatapb.VReplicationWorkflowType_CreateLookupIndex { + // Return an error if the workflow traffic is partially switched. + if state.WritesSwitched || len(state.ReplicaCellsSwitched) > 0 || len(state.RdonlyCellsSwitched) > 0 { + return nil, ErrWorkflowPartiallySwitched } + } + + if state.WorkflowType == TypeMigrate { + _, err := s.finalizeMigrateWorkflow(ctx, ts, "", true, req.GetKeepData(), req.GetKeepRoutingRules(), false) return nil, err } @@ -1993,7 +2041,9 @@ func (s *Server) WorkflowDelete(ctx context.Context, req *vtctldatapb.WorkflowDe s.optimizeCopyStateTable(tablet.Tablet) return res.Result, err } - res, err := vx.CallbackContext(ctx, callback) + delCtx, delCancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout*2) + defer delCancel() + res, err := vx.CallbackContext(delCtx, callback) if err != nil { return nil, err } @@ -2002,6 +2052,16 @@ func (s *Server) WorkflowDelete(ctx context.Context, req *vtctldatapb.WorkflowDe return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "the %s workflow does not exist in the %s keyspace", req.Workflow, req.Keyspace) } + // Cleanup related data and artifacts. There are none for a LookupVindex workflow. + if ts.workflowType != binlogdatapb.VReplicationWorkflowType_CreateLookupIndex { + if _, err := s.DropTargets(delCtx, ts, req.GetKeepData(), req.GetKeepRoutingRules(), false); err != nil { + if topo.IsErrType(err, topo.NoNode) { + return nil, vterrors.Wrapf(err, "%s keyspace does not exist", req.GetKeyspace()) + } + return nil, err + } + } + response := &vtctldatapb.WorkflowDeleteResponse{} response.Summary = fmt.Sprintf("Successfully cancelled the %s workflow in the %s keyspace", req.Workflow, req.Keyspace) details := make([]*vtctldatapb.WorkflowDeleteResponse_TabletInfo, 0, len(res)) @@ -2012,6 +2072,9 @@ func (s *Server) WorkflowDelete(ctx context.Context, req *vtctldatapb.WorkflowDe } details = append(details, result) } + sort.Slice(details, func(i, j int) bool { // Ensure deterministic output + return topoproto.TabletAliasString(details[i].Tablet) < topoproto.TabletAliasString(details[j].Tablet) + }) response.Details = details return response, nil } @@ -2269,7 +2332,9 @@ func (s *Server) WorkflowUpdate(ctx context.Context, req *vtctldatapb.WorkflowUp } return res.Result, err } - res, err := vx.CallbackContext(ctx, callback) + updCtx, updCancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout*2) + defer updCancel() + res, err := vx.CallbackContext(updCtx, callback) if err != nil { if topo.IsErrType(err, topo.NoNode) { return nil, vterrors.Wrapf(err, "%s keyspace does not exist", req.Keyspace) @@ -2497,28 +2562,8 @@ func (s *Server) optimizeCopyStateTable(tablet *topodatapb.Tablet) { // DropTargets cleans up target tables, shards and denied tables if a MoveTables/Reshard // is cancelled. -func (s *Server) DropTargets(ctx context.Context, targetKeyspace, workflow string, keepData, keepRoutingRules, dryRun bool) (*[]string, error) { - ts, state, err := s.getWorkflowState(ctx, targetKeyspace, workflow) - if err != nil { - log.Errorf("Failed to get VReplication workflow state for %s.%s: %v", targetKeyspace, workflow, err) - return nil, err - } - - // There is nothing to drop for a LookupVindex workflow. - if ts.workflowType == binlogdatapb.VReplicationWorkflowType_CreateLookupIndex { - return nil, nil - } - - // Return an error if the workflow traffic is partially switched. - if state.WritesSwitched || len(state.ReplicaCellsSwitched) > 0 || len(state.RdonlyCellsSwitched) > 0 { - return nil, ErrWorkflowPartiallySwitched - } - - if state.WorkflowType == TypeMigrate { - _, err := s.finalizeMigrateWorkflow(ctx, targetKeyspace, workflow, "", true, keepData, keepRoutingRules, dryRun) - return nil, err - } - +func (s *Server) DropTargets(ctx context.Context, ts *trafficSwitcher, keepData, keepRoutingRules, dryRun bool) (*[]string, error) { + var err error ts.keepRoutingRules = keepRoutingRules var sw iswitcher if dryRun { @@ -2629,7 +2674,7 @@ func (s *Server) buildTrafficSwitcher(ctx context.Context, targetKeyspace, workf tables = append(tables, rule.Match) } sort.Strings(tables) - if !reflect.DeepEqual(ts.tables, tables) { + if !slices.Equal(ts.tables, tables) { return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "table lists are mismatched across streams: %v vs %v", ts.tables, tables) } } @@ -2803,8 +2848,8 @@ func (s *Server) DeleteShard(ctx context.Context, keyspace, shard string, recurs shardInfo, err := s.ts.GetShard(ctx, keyspace, shard) if err != nil { if topo.IsErrType(err, topo.NoNode) { - log.Infof("Shard %v/%v doesn't seem to exist, cleaning up any potential leftover", keyspace, shard) - return s.ts.DeleteShard(ctx, keyspace, shard) + log.Warningf("Shard %v/%v did not exist when attempting to remove it", keyspace, shard) + return nil } return err } @@ -2942,13 +2987,11 @@ func (s *Server) refreshPrimaryTablets(ctx context.Context, shards []*topo.Shard // finalizeMigrateWorkflow deletes the streams for the Migrate workflow. // We only cleanup the target for external sources. -func (s *Server) finalizeMigrateWorkflow(ctx context.Context, targetKeyspace, workflow, tableSpecs string, cancel, keepData, keepRoutingRules, dryRun bool) (*[]string, error) { - ts, err := s.buildTrafficSwitcher(ctx, targetKeyspace, workflow) - if err != nil { - ts.Logger().Errorf("buildTrafficSwitcher failed: %v", err) - return nil, err - } - var sw iswitcher +func (s *Server) finalizeMigrateWorkflow(ctx context.Context, ts *trafficSwitcher, tableSpecs string, cancel, keepData, keepRoutingRules, dryRun bool) (*[]string, error) { + var ( + sw iswitcher + err error + ) if dryRun { sw = &switcherDryRun{ts: ts, drLog: NewLogRecorder()} } else { @@ -2966,7 +3009,7 @@ func (s *Server) finalizeMigrateWorkflow(ctx context.Context, targetKeyspace, wo return nil, err } if !cancel { - if err := sw.addParticipatingTablesToKeyspace(ctx, targetKeyspace, tableSpecs); err != nil { + if err := sw.addParticipatingTablesToKeyspace(ctx, ts.targetKeyspace, tableSpecs); err != nil { return nil, err } if err := ts.TopoServer().RebuildSrvVSchema(ctx, nil); err != nil { @@ -3072,7 +3115,7 @@ func (s *Server) WorkflowSwitchTraffic(ctx context.Context, req *vtctldatapb.Wor resp.Summary = fmt.Sprintf("%s dry run results for workflow %s.%s at %v", cmd, req.Keyspace, req.Workflow, time.Now().UTC().Format(time.RFC822)) resp.DryRunResults = dryRunResults } else { - log.Infof("SwitchTraffic done for workflow %s.%s", req.Keyspace, req.Workflow) + log.Infof("%s done for workflow %s.%s", cmd, req.Keyspace, req.Workflow) resp.Summary = fmt.Sprintf("%s was successful for workflow %s.%s", cmd, req.Keyspace, req.Workflow) // Reload the state after the SwitchTraffic operation // and return that as a string. @@ -3090,7 +3133,7 @@ func (s *Server) WorkflowSwitchTraffic(ctx context.Context, req *vtctldatapb.Wor } else { resp.CurrentState = currentState.String() } - log.Infof("SwitchTraffic done for workflow %s.%s, returning response %v", req.Keyspace, req.Workflow, resp) + log.Infof("%s done for workflow %s.%s, returning response %v", cmd, req.Keyspace, req.Workflow, resp) } return resp, nil } diff --git a/go/vt/vtctl/workflow/server_test.go b/go/vt/vtctl/workflow/server_test.go index 174cc2aaf6a..fb432403155 100644 --- a/go/vt/vtctl/workflow/server_test.go +++ b/go/vt/vtctl/workflow/server_test.go @@ -19,7 +19,11 @@ package workflow import ( "context" "fmt" + "slices" + "sort" + "strings" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -27,6 +31,7 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/utils" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vtenv" @@ -34,6 +39,7 @@ import ( binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) @@ -199,3 +205,578 @@ func TestVDiffCreate(t *testing.T) { }) } } + +func TestWorkflowDelete(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + tableName := "t1" + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + schema := map[string]*tabletmanagerdatapb.SchemaDefinition{ + "t1": { + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: tableName, + Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", tableName), + }, + }, + }, + } + + testcases := []struct { + name string + sourceKeyspace, targetKeyspace *testKeyspace + preFunc func(t *testing.T, env *testEnv) + req *vtctldatapb.WorkflowDeleteRequest + expectedSourceQueries []*queryResult + expectedTargetQueries []*queryResult + want *vtctldatapb.WorkflowDeleteResponse + wantErr bool + postFunc func(t *testing.T, env *testEnv) + }{ + { + name: "basic", + sourceKeyspace: &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + }, + targetKeyspace: &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"-80", "80-"}, + }, + req: &vtctldatapb.WorkflowDeleteRequest{ + Keyspace: targetKeyspaceName, + Workflow: workflowName, + }, + expectedSourceQueries: []*queryResult{ + { + query: fmt.Sprintf("delete from _vt.vreplication where db_name = 'vt_%s' and workflow = '%s'", + sourceKeyspaceName, ReverseWorkflowName(workflowName)), + result: &querypb.QueryResult{}, + }, + }, + expectedTargetQueries: []*queryResult{ + { + query: fmt.Sprintf("drop table `vt_%s`.`%s`", targetKeyspaceName, tableName), + result: &querypb.QueryResult{}, + }, + }, + want: &vtctldatapb.WorkflowDeleteResponse{ + Summary: fmt.Sprintf("Successfully cancelled the %s workflow in the %s keyspace", + workflowName, targetKeyspaceName), + Details: []*vtctldatapb.WorkflowDeleteResponse_TabletInfo{ + { + Tablet: &topodatapb.TabletAlias{Cell: defaultCellName, Uid: startingTargetTabletUID}, + Deleted: true, + }, + { + Tablet: &topodatapb.TabletAlias{Cell: defaultCellName, Uid: startingTargetTabletUID + tabletUIDStep}, + Deleted: true, + }, + }, + }, + }, + { + name: "basic with existing denied table entries", + sourceKeyspace: &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + }, + targetKeyspace: &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"-80", "80-"}, + }, + preFunc: func(t *testing.T, env *testEnv) { + lockCtx, targetUnlock, lockErr := env.ts.LockKeyspace(ctx, targetKeyspaceName, "test") + require.NoError(t, lockErr) + var err error + defer require.NoError(t, err) + defer targetUnlock(&err) + for _, shard := range env.targetKeyspace.ShardNames { + _, err := env.ts.UpdateShardFields(lockCtx, targetKeyspaceName, shard, func(si *topo.ShardInfo) error { + err := si.UpdateDeniedTables(lockCtx, topodatapb.TabletType_PRIMARY, nil, false, []string{tableName, "t2", "t3"}) + return err + }) + require.NoError(t, err) + } + }, + req: &vtctldatapb.WorkflowDeleteRequest{ + Keyspace: targetKeyspaceName, + Workflow: workflowName, + }, + expectedSourceQueries: []*queryResult{ + { + query: fmt.Sprintf("delete from _vt.vreplication where db_name = 'vt_%s' and workflow = '%s'", + sourceKeyspaceName, ReverseWorkflowName(workflowName)), + result: &querypb.QueryResult{}, + }, + }, + expectedTargetQueries: []*queryResult{ + { + query: fmt.Sprintf("drop table `vt_%s`.`%s`", targetKeyspaceName, tableName), + result: &querypb.QueryResult{}, + }, + }, + want: &vtctldatapb.WorkflowDeleteResponse{ + Summary: fmt.Sprintf("Successfully cancelled the %s workflow in the %s keyspace", + workflowName, targetKeyspaceName), + Details: []*vtctldatapb.WorkflowDeleteResponse_TabletInfo{ + { + Tablet: &topodatapb.TabletAlias{Cell: defaultCellName, Uid: startingTargetTabletUID}, + Deleted: true, + }, + { + Tablet: &topodatapb.TabletAlias{Cell: defaultCellName, Uid: startingTargetTabletUID + tabletUIDStep}, + Deleted: true, + }, + }, + }, + postFunc: func(t *testing.T, env *testEnv) { + for _, shard := range env.targetKeyspace.ShardNames { + si, err := env.ts.GetShard(ctx, targetKeyspaceName, shard) + require.NoError(t, err) + require.NotNil(t, si) + tc := si.GetTabletControl(topodatapb.TabletType_PRIMARY) + require.NotNil(t, tc) + require.EqualValues(t, []string{"t2", "t3"}, tc.DeniedTables) + } + }, + }, + } + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + require.NotNil(t, tc.sourceKeyspace) + require.NotNil(t, tc.targetKeyspace) + require.NotNil(t, tc.req) + env := newTestEnv(t, ctx, defaultCellName, tc.sourceKeyspace, tc.targetKeyspace) + defer env.close() + env.tmc.schema = schema + if tc.expectedSourceQueries != nil { + require.NotNil(t, env.tablets[tc.sourceKeyspace.KeyspaceName]) + for _, eq := range tc.expectedSourceQueries { + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, eq) + } + } + if tc.expectedTargetQueries != nil { + require.NotNil(t, env.tablets[tc.targetKeyspace.KeyspaceName]) + for _, eq := range tc.expectedTargetQueries { + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, eq) + } + } + if tc.preFunc != nil { + tc.preFunc(t, env) + } + got, err := env.ws.WorkflowDelete(ctx, tc.req) + if (err != nil) != tc.wantErr { + require.Fail(t, "unexpected error value", "Server.WorkflowDelete() error = %v, wantErr %v", err, tc.wantErr) + return + } + require.EqualValues(t, got, tc.want, "Server.WorkflowDelete() = %v, want %v", got, tc.want) + if tc.postFunc != nil { + tc.postFunc(t, env) + } else { // Default post checks + // Confirm that we have no routing rules. + rr, err := env.ts.GetRoutingRules(ctx) + require.NoError(t, err) + require.Zero(t, rr.Rules) + + // Confirm that we have no shard tablet controls, which is where + // DeniedTables live. + for _, keyspace := range []*testKeyspace{tc.sourceKeyspace, tc.targetKeyspace} { + for _, shardName := range keyspace.ShardNames { + si, err := env.ts.GetShard(ctx, keyspace.KeyspaceName, shardName) + require.NoError(t, err) + require.Zero(t, si.Shard.TabletControls) + } + } + } + }) + } +} + +func TestMoveTablesTrafficSwitching(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + tableName := "t1" + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + vrID := 1 + tabletTypes := []topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + topodatapb.TabletType_REPLICA, + topodatapb.TabletType_RDONLY, + } + schema := map[string]*tabletmanagerdatapb.SchemaDefinition{ + tableName: { + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: tableName, + Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", tableName), + }, + }, + }, + } + copyTableQR := &queryResult{ + query: fmt.Sprintf("select vrepl_id, table_name, lastpk from _vt.copy_state where vrepl_id in (%d) and id in (select max(id) from _vt.copy_state where vrepl_id in (%d) group by vrepl_id, table_name)", + vrID, vrID), + result: &querypb.QueryResult{}, + } + journalQR := &queryResult{ + query: "/select val from _vt.resharding_journal.*", + result: &querypb.QueryResult{}, + } + lockTableQR := &queryResult{ + query: fmt.Sprintf("LOCK TABLES `%s` READ", tableName), + result: &querypb.QueryResult{}, + } + cutoverQR := &queryResult{ + query: "/update _vt.vreplication set state='Stopped', message='stopped for cutover' where id=.*", + result: &querypb.QueryResult{}, + } + createWFQR := &queryResult{ + query: "/insert into _vt.vreplication.*", + result: &querypb.QueryResult{}, + } + deleteWFQR := &queryResult{ + query: fmt.Sprintf("delete from _vt.vreplication where db_name = 'vt_%s' and workflow = '%s'", targetKeyspaceName, workflowName), + result: &querypb.QueryResult{}, + } + deleteReverseWFQR := &queryResult{ + query: fmt.Sprintf("delete from _vt.vreplication where db_name = 'vt_%s' and workflow = '%s'", sourceKeyspaceName, ReverseWorkflowName(workflowName)), + result: &querypb.QueryResult{}, + } + createReverseWFQR := &queryResult{ + query: "/insert into _vt.vreplication.*_reverse.*", + result: &querypb.QueryResult{}, + } + createJournalQR := &queryResult{ + query: "/insert into _vt.resharding_journal.*", + result: &querypb.QueryResult{}, + } + freezeWFQR := &queryResult{ + query: fmt.Sprintf("update _vt.vreplication set message = 'FROZEN' where db_name='vt_%s' and workflow='%s'", targetKeyspaceName, workflowName), + result: &querypb.QueryResult{}, + } + freezeReverseWFQR := &queryResult{ + query: fmt.Sprintf("update _vt.vreplication set message = 'FROZEN' where db_name='vt_%s' and workflow='%s'", sourceKeyspaceName, ReverseWorkflowName(workflowName)), + result: &querypb.QueryResult{}, + } + + hasDeniedTableEntry := func(si *topo.ShardInfo) bool { + if si == nil || len(si.TabletControls) == 0 { + return false + } + for _, tc := range si.Shard.TabletControls { + return slices.Equal(tc.DeniedTables, []string{tableName}) + } + return false + } + + testcases := []struct { + name string + sourceKeyspace, targetKeyspace *testKeyspace + req *vtctldatapb.WorkflowSwitchTrafficRequest + want *vtctldatapb.WorkflowSwitchTrafficResponse + wantErr bool + }{ + { + name: "basic forward", + sourceKeyspace: &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + }, + targetKeyspace: &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"-80", "80-"}, + }, + req: &vtctldatapb.WorkflowSwitchTrafficRequest{ + Keyspace: targetKeyspaceName, + Workflow: workflowName, + Direction: int32(DirectionForward), + TabletTypes: tabletTypes, + }, + want: &vtctldatapb.WorkflowSwitchTrafficResponse{ + Summary: fmt.Sprintf("SwitchTraffic was successful for workflow %s.%s", targetKeyspaceName, workflowName), + StartState: "Reads Not Switched. Writes Not Switched", + CurrentState: "All Reads Switched. Writes Switched", + }, + }, + { + name: "basic backward", + sourceKeyspace: &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + }, + targetKeyspace: &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"-80", "80-"}, + }, + req: &vtctldatapb.WorkflowSwitchTrafficRequest{ + Keyspace: targetKeyspaceName, + Workflow: workflowName, + Direction: int32(DirectionBackward), + TabletTypes: tabletTypes, + }, + want: &vtctldatapb.WorkflowSwitchTrafficResponse{ + Summary: fmt.Sprintf("ReverseTraffic was successful for workflow %s.%s", targetKeyspaceName, workflowName), + StartState: "All Reads Switched. Writes Switched", + CurrentState: "Reads Not Switched. Writes Not Switched", + }, + }, + } + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + require.NotNil(t, tc.sourceKeyspace) + require.NotNil(t, tc.targetKeyspace) + require.NotNil(t, tc.req) + env := newTestEnv(t, ctx, defaultCellName, tc.sourceKeyspace, tc.targetKeyspace) + defer env.close() + env.tmc.schema = schema + if tc.req.Direction == int32(DirectionForward) { + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, copyTableQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, cutoverQR) + for i := 0; i < len(tc.targetKeyspace.ShardNames); i++ { // Per stream + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, journalQR) + } + for i := 0; i < len(tc.targetKeyspace.ShardNames); i++ { // Per stream + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, lockTableQR) + } + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, deleteReverseWFQR) + for i := 0; i < len(tc.targetKeyspace.ShardNames); i++ { // Per stream + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, createReverseWFQR) + } + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, createJournalQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, freezeWFQR) + } else { + env.tmc.reverse.Store(true) + // Setup the routing rules as they would be after having previously done SwitchTraffic. + env.addTableRoutingRules(t, ctx, tabletTypes, []string{tableName}) + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, copyTableQR) + for i := 0; i < len(tc.targetKeyspace.ShardNames); i++ { // Per stream + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, cutoverQR) + } + for i := 0; i < len(tc.targetKeyspace.ShardNames); i++ { // Per stream + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, journalQR) + } + for i := 0; i < len(tc.targetKeyspace.ShardNames); i++ { // Per stream + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, lockTableQR) + } + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, deleteWFQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, createWFQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, createJournalQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, freezeReverseWFQR) + } + got, err := env.ws.WorkflowSwitchTraffic(ctx, tc.req) + if (err != nil) != tc.wantErr { + require.Fail(t, "unexpected error value", "Server.WorkflowSwitchTraffic() error = %v, wantErr %v", err, tc.wantErr) + return + } + require.Equal(t, tc.want.String(), got.String(), "Server.WorkflowSwitchTraffic() = %v, want %v", got, tc.want) + + // Confirm that we have the expected routing rules. + rr, err := env.ts.GetRoutingRules(ctx) + require.NoError(t, err) + to := fmt.Sprintf("%s.%s", tc.targetKeyspace.KeyspaceName, tableName) + if tc.req.Direction == int32(DirectionBackward) { + to = fmt.Sprintf("%s.%s", tc.sourceKeyspace.KeyspaceName, tableName) + } + for _, rr := range rr.Rules { + for _, tt := range rr.ToTables { + require.Equal(t, to, tt) + } + } + // Confirm that we have the expected denied tables entires. + for _, keyspace := range []*testKeyspace{tc.sourceKeyspace, tc.targetKeyspace} { + for _, shardName := range keyspace.ShardNames { + si, err := env.ts.GetShard(ctx, keyspace.KeyspaceName, shardName) + require.NoError(t, err) + switch { + case keyspace == tc.sourceKeyspace && tc.req.Direction == int32(DirectionForward): + require.True(t, hasDeniedTableEntry(si)) + case keyspace == tc.sourceKeyspace && tc.req.Direction == int32(DirectionBackward): + require.False(t, hasDeniedTableEntry(si)) + case keyspace == tc.targetKeyspace && tc.req.Direction == int32(DirectionForward): + require.False(t, hasDeniedTableEntry(si)) + case keyspace == tc.targetKeyspace && tc.req.Direction == int32(DirectionBackward): + require.True(t, hasDeniedTableEntry(si)) + } + } + } + }) + } +} + +func TestMoveTablesTrafficSwitchingDryRun(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + table1Name := "t1" + table2Name := "a1" + tables := []string{table1Name, table2Name} + sort.Strings(tables) + tablesStr := strings.Join(tables, ",") + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + vrID := 1 + tabletTypes := []topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + topodatapb.TabletType_REPLICA, + topodatapb.TabletType_RDONLY, + } + schema := map[string]*tabletmanagerdatapb.SchemaDefinition{ + table1Name: { + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: table1Name, + Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", table1Name), + }, + }, + }, + table2Name: { + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: table2Name, + Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", table2Name), + }, + }, + }, + } + copyTableQR := &queryResult{ + query: fmt.Sprintf("select vrepl_id, table_name, lastpk from _vt.copy_state where vrepl_id in (%d) and id in (select max(id) from _vt.copy_state where vrepl_id in (%d) group by vrepl_id, table_name)", + vrID, vrID), + result: &querypb.QueryResult{}, + } + journalQR := &queryResult{ + query: "/select val from _vt.resharding_journal.*", + result: &querypb.QueryResult{}, + } + lockTableQR := &queryResult{ + query: fmt.Sprintf("LOCK TABLES `%s` READ,`%s` READ", table2Name, table1Name), + result: &querypb.QueryResult{}, + } + + testcases := []struct { + name string + sourceKeyspace, targetKeyspace *testKeyspace + req *vtctldatapb.WorkflowSwitchTrafficRequest + want []string + }{ + { + name: "basic forward", + sourceKeyspace: &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"-80", "80-"}, + }, + targetKeyspace: &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"-80", "80-"}, + }, + req: &vtctldatapb.WorkflowSwitchTrafficRequest{ + Keyspace: targetKeyspaceName, + Workflow: workflowName, + Direction: int32(DirectionForward), + TabletTypes: tabletTypes, + DryRun: true, + }, + want: []string{ + fmt.Sprintf("Lock keyspace %s", sourceKeyspaceName), + fmt.Sprintf("Switch reads for tables [%s] to keyspace %s for tablet types [REPLICA,RDONLY]", tablesStr, targetKeyspaceName), + fmt.Sprintf("Routing rules for tables [%s] will be updated", tablesStr), + fmt.Sprintf("Unlock keyspace %s", sourceKeyspaceName), + fmt.Sprintf("Lock keyspace %s", sourceKeyspaceName), + fmt.Sprintf("Lock keyspace %s", targetKeyspaceName), + fmt.Sprintf("Stop writes on keyspace %s for tables [%s]: [keyspace:%s;shard:-80;position:%s,keyspace:%s;shard:80-;position:%s]", + sourceKeyspaceName, tablesStr, sourceKeyspaceName, position, sourceKeyspaceName, position), + "Wait for vreplication on stopped streams to catchup for up to 30s", + fmt.Sprintf("Create reverse vreplication workflow %s", ReverseWorkflowName(workflowName)), + "Create journal entries on source databases", + fmt.Sprintf("Enable writes on keyspace %s for tables [%s]", targetKeyspaceName, tablesStr), + fmt.Sprintf("Switch routing from keyspace %s to keyspace %s", sourceKeyspaceName, targetKeyspaceName), + fmt.Sprintf("Routing rules for tables [%s] will be updated", tablesStr), + fmt.Sprintf("Switch writes completed, freeze and delete vreplication streams on: [tablet:%d,tablet:%d]", startingTargetTabletUID, startingTargetTabletUID+tabletUIDStep), + fmt.Sprintf("Mark vreplication streams frozen on: [keyspace:%s;shard:-80;tablet:%d;workflow:%s;dbname:vt_%s,keyspace:%s;shard:80-;tablet:%d;workflow:%s;dbname:vt_%s]", + targetKeyspaceName, startingTargetTabletUID, workflowName, targetKeyspaceName, targetKeyspaceName, startingTargetTabletUID+tabletUIDStep, workflowName, targetKeyspaceName), + fmt.Sprintf("Unlock keyspace %s", targetKeyspaceName), + fmt.Sprintf("Unlock keyspace %s", sourceKeyspaceName), + }, + }, + { + name: "basic backward", + sourceKeyspace: &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"-80", "80-"}, + }, + targetKeyspace: &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"-80", "80-"}, + }, + req: &vtctldatapb.WorkflowSwitchTrafficRequest{ + Keyspace: targetKeyspaceName, + Workflow: workflowName, + Direction: int32(DirectionBackward), + TabletTypes: tabletTypes, + DryRun: true, + }, + want: []string{ + fmt.Sprintf("Lock keyspace %s", targetKeyspaceName), + fmt.Sprintf("Switch reads for tables [%s] to keyspace %s for tablet types [REPLICA,RDONLY]", tablesStr, targetKeyspaceName), + fmt.Sprintf("Routing rules for tables [%s] will be updated", tablesStr), + fmt.Sprintf("Unlock keyspace %s", targetKeyspaceName), + fmt.Sprintf("Lock keyspace %s", targetKeyspaceName), + fmt.Sprintf("Lock keyspace %s", sourceKeyspaceName), + fmt.Sprintf("Stop writes on keyspace %s for tables [%s]: [keyspace:%s;shard:-80;position:%s,keyspace:%s;shard:80-;position:%s]", + targetKeyspaceName, tablesStr, targetKeyspaceName, position, targetKeyspaceName, position), + "Wait for vreplication on stopped streams to catchup for up to 30s", + fmt.Sprintf("Create reverse vreplication workflow %s", workflowName), + "Create journal entries on source databases", + fmt.Sprintf("Enable writes on keyspace %s for tables [%s]", sourceKeyspaceName, tablesStr), + fmt.Sprintf("Switch routing from keyspace %s to keyspace %s", targetKeyspaceName, sourceKeyspaceName), + fmt.Sprintf("Routing rules for tables [%s] will be updated", tablesStr), + fmt.Sprintf("Switch writes completed, freeze and delete vreplication streams on: [tablet:%d,tablet:%d]", startingSourceTabletUID, startingSourceTabletUID+tabletUIDStep), + fmt.Sprintf("Mark vreplication streams frozen on: [keyspace:%s;shard:-80;tablet:%d;workflow:%s;dbname:vt_%s,keyspace:%s;shard:80-;tablet:%d;workflow:%s;dbname:vt_%s]", + sourceKeyspaceName, startingSourceTabletUID, ReverseWorkflowName(workflowName), sourceKeyspaceName, sourceKeyspaceName, startingSourceTabletUID+tabletUIDStep, ReverseWorkflowName(workflowName), sourceKeyspaceName), + fmt.Sprintf("Unlock keyspace %s", sourceKeyspaceName), + fmt.Sprintf("Unlock keyspace %s", targetKeyspaceName), + }, + }, + } + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + require.NotNil(t, tc.sourceKeyspace) + require.NotNil(t, tc.targetKeyspace) + require.NotNil(t, tc.req) + env := newTestEnv(t, ctx, defaultCellName, tc.sourceKeyspace, tc.targetKeyspace) + defer env.close() + env.tmc.schema = schema + if tc.req.Direction == int32(DirectionForward) { + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, copyTableQR) + for i := 0; i < len(tc.targetKeyspace.ShardNames); i++ { // Per stream + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, journalQR) + } + for i := 0; i < len(tc.targetKeyspace.ShardNames); i++ { // Per stream + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, lockTableQR) + } + } else { + env.tmc.reverse.Store(true) + // Setup the routing rules as they would be after having previously done SwitchTraffic. + env.addTableRoutingRules(t, ctx, tabletTypes, tables) + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.sourceKeyspace.KeyspaceName, copyTableQR) + for i := 0; i < len(tc.targetKeyspace.ShardNames); i++ { // Per stream + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, journalQR) + } + for i := 0; i < len(tc.targetKeyspace.ShardNames); i++ { // Per stream + env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, lockTableQR) + } + } + got, err := env.ws.WorkflowSwitchTraffic(ctx, tc.req) + require.NoError(t, err) + + require.EqualValues(t, tc.want, got.DryRunResults, "Server.WorkflowSwitchTraffic(DryRun:true) = %v, want %v", got.DryRunResults, tc.want) + }) + } +} diff --git a/go/vt/vtctl/workflow/switcher_dry_run.go b/go/vt/vtctl/workflow/switcher_dry_run.go index 03faa4c4ca2..b8b1369bdf7 100644 --- a/go/vt/vtctl/workflow/switcher_dry_run.go +++ b/go/vt/vtctl/workflow/switcher_dry_run.go @@ -82,6 +82,7 @@ func (dr *switcherDryRun) switchShardReads(ctx context.Context, cells []string, for _, target := range dr.ts.Targets() { targetShards = append(targetShards, target.GetShard().ShardName()) } + // Sort the slices for deterministic output. sort.Strings(sourceShards) sort.Strings(targetShards) if direction == DirectionForward { @@ -103,6 +104,7 @@ func (dr *switcherDryRun) switchTableReads(ctx context.Context, cells []string, for _, servedType := range servedTypes { tabletTypes = append(tabletTypes, servedType.String()) } + sort.Strings(dr.ts.Tables()) // For deterministic output tables := strings.Join(dr.ts.Tables(), ",") dr.drLog.Logf("Switch reads for tables [%s] to keyspace %s for tablet types [%s]", tables, ks, strings.Join(tabletTypes, ",")) dr.drLog.Logf("Routing rules for tables [%s] will be updated", tables) @@ -114,6 +116,7 @@ func (dr *switcherDryRun) switchTableReads(ctx context.Context, cells []string, func (dr *switcherDryRun) createJournals(ctx context.Context, sourceWorkflows []string) error { dr.drLog.Log("Create journal entries on source databases") + sort.Strings(sourceWorkflows) // For deterministic output if len(sourceWorkflows) > 0 { dr.drLog.Logf("Source workflows found: [%s]", strings.Join(sourceWorkflows, ",")) } @@ -121,6 +124,7 @@ func (dr *switcherDryRun) createJournals(ctx context.Context, sourceWorkflows [] } func (dr *switcherDryRun) allowTargetWrites(ctx context.Context) error { + sort.Strings(dr.ts.Tables()) // For deterministic output dr.drLog.Logf("Enable writes on keyspace %s for tables [%s]", dr.ts.TargetKeyspaceName(), strings.Join(dr.ts.Tables(), ",")) return nil } @@ -129,16 +133,27 @@ func (dr *switcherDryRun) changeRouting(ctx context.Context) error { dr.drLog.Logf("Switch routing from keyspace %s to keyspace %s", dr.ts.SourceKeyspaceName(), dr.ts.TargetKeyspaceName()) var deleteLogs, addLogs []string if dr.ts.MigrationType() == binlogdatapb.MigrationType_TABLES { + sort.Strings(dr.ts.Tables()) // For deterministic output tables := strings.Join(dr.ts.Tables(), ",") dr.drLog.Logf("Routing rules for tables [%s] will be updated", tables) return nil } deleteLogs = nil addLogs = nil - for _, source := range dr.ts.Sources() { + sources := maps.Values(dr.ts.Sources()) + // Sort the slice for deterministic output. + sort.Slice(sources, func(i, j int) bool { + return sources[i].GetPrimary().Alias.Uid < sources[j].GetPrimary().Alias.Uid + }) + for _, source := range sources { deleteLogs = append(deleteLogs, fmt.Sprintf("shard:%s;tablet:%d", source.GetShard().ShardName(), source.GetShard().PrimaryAlias.Uid)) } - for _, target := range dr.ts.Targets() { + targets := maps.Values(dr.ts.Targets()) + // Sort the slice for deterministic output. + sort.Slice(targets, func(i, j int) bool { + return targets[i].GetPrimary().Alias.Uid < targets[j].GetPrimary().Alias.Uid + }) + for _, target := range targets { addLogs = append(addLogs, fmt.Sprintf("shard:%s;tablet:%d", target.GetShard().ShardName(), target.GetShard().PrimaryAlias.Uid)) } if len(deleteLogs) > 0 { @@ -150,7 +165,12 @@ func (dr *switcherDryRun) changeRouting(ctx context.Context) error { func (dr *switcherDryRun) streamMigraterfinalize(ctx context.Context, ts *trafficSwitcher, workflows []string) error { logs := make([]string, 0) - for _, t := range ts.Targets() { + targets := maps.Values(ts.Targets()) + // Sort the slice for deterministic output. + sort.Slice(targets, func(i, j int) bool { + return targets[i].GetPrimary().Alias.Uid < targets[j].GetPrimary().Alias.Uid + }) + for _, t := range targets { logs = append(logs, fmt.Sprintf("tablet:%d", t.GetPrimary().Alias.Uid)) } dr.drLog.Logf("Switch writes completed, freeze and delete vreplication streams on: [%s]", strings.Join(logs, ",")) @@ -159,7 +179,12 @@ func (dr *switcherDryRun) streamMigraterfinalize(ctx context.Context, ts *traffi func (dr *switcherDryRun) startReverseVReplication(ctx context.Context) error { logs := make([]string, 0) - for _, t := range dr.ts.Sources() { + sources := maps.Values(dr.ts.Sources()) + // Sort the slice for deterministic output. + sort.Slice(sources, func(i, j int) bool { + return sources[i].GetPrimary().Alias.Uid < sources[j].GetPrimary().Alias.Uid + }) + for _, t := range sources { logs = append(logs, fmt.Sprintf("tablet:%d", t.GetPrimary().Alias.Uid)) } dr.drLog.Logf("Start reverse vreplication streams on: [%s]", strings.Join(logs, ",")) @@ -180,17 +205,33 @@ func (dr *switcherDryRun) migrateStreams(ctx context.Context, sm *StreamMigrator logs := make([]string, 0) dr.drLog.Logf("Migrate streams to %s:", dr.ts.TargetKeyspaceName()) - for key, streams := range sm.Streams() { - for _, stream := range streams { - logs = append(logs, fmt.Sprintf("shard:%s;id:%d;workflow:%s;position:%s;binlogsource:%v", key, stream.ID, stream.Workflow, replication.EncodePosition(stream.Position), stream.BinlogSource)) + allStreams := sm.Streams() + // Sort the keys and slices for deterministic output. + shards := maps.Keys(sm.Streams()) + sort.Strings(shards) + for _, shard := range shards { + shardStreams := allStreams[shard] + sort.Slice(shardStreams, func(i, j int) bool { + return shardStreams[i].ID < shardStreams[j].ID + }) + for _, stream := range shardStreams { + logs = append(logs, fmt.Sprintf("shard:%s;id:%d;workflow:%s;position:%s;binlogsource:%v", shard, stream.ID, stream.Workflow, replication.EncodePosition(stream.Position), stream.BinlogSource)) } } if len(logs) > 0 { dr.drLog.Logf("Migrate source streams: [%s]", strings.Join(logs, ",")) logs = nil } - for _, target := range dr.ts.Targets() { + // Sort the keys and slices for deterministic output. + targets := maps.Values(dr.ts.Targets()) + sort.Slice(targets, func(i, j int) bool { + return targets[i].GetPrimary().Alias.Uid < targets[j].GetPrimary().Alias.Uid + }) + for _, target := range targets { tabletStreams := templates + sort.Slice(tabletStreams, func(i, j int) bool { + return tabletStreams[i].ID < tabletStreams[j].ID + }) for _, vrs := range tabletStreams { logs = append(logs, fmt.Sprintf("keyspace:%s;shard:%s;tablet:%d;workflow:%s;id:%d,position:%v;binlogsource:%s", vrs.BinlogSource.Keyspace, vrs.BinlogSource.Shard, target.GetPrimary().Alias.Uid, vrs.Workflow, vrs.ID, replication.EncodePosition(vrs.Position), vrs.BinlogSource)) @@ -209,10 +250,16 @@ func (dr *switcherDryRun) waitForCatchup(ctx context.Context, filteredReplicatio func (dr *switcherDryRun) stopSourceWrites(ctx context.Context) error { logs := make([]string, 0) - for _, source := range dr.ts.Sources() { + sources := maps.Values(dr.ts.Sources()) + // Sort the slice for deterministic output. + sort.Slice(sources, func(i, j int) bool { + return sources[i].GetPrimary().Alias.Uid < sources[j].GetPrimary().Alias.Uid + }) + for _, source := range sources { position, _ := dr.ts.TabletManagerClient().PrimaryPosition(ctx, source.GetPrimary().Tablet) logs = append(logs, fmt.Sprintf("keyspace:%s;shard:%s;position:%s", dr.ts.SourceKeyspaceName(), source.GetShard().ShardName(), position)) } + sort.Strings(dr.ts.Tables()) // For deterministic output if len(logs) > 0 { dr.drLog.Logf("Stop writes on keyspace %s for tables [%s]: [%s]", dr.ts.SourceKeyspaceName(), strings.Join(dr.ts.Tables(), ","), strings.Join(logs, ",")) @@ -222,8 +269,16 @@ func (dr *switcherDryRun) stopSourceWrites(ctx context.Context) error { func (dr *switcherDryRun) stopStreams(ctx context.Context, sm *StreamMigrator) ([]string, error) { logs := make([]string, 0) - for _, streams := range sm.Streams() { - for _, stream := range streams { + allStreams := sm.Streams() + // Sort the keys and slices for deterministic output. + shards := maps.Keys(sm.Streams()) + sort.Strings(shards) + for _, shard := range shards { + shardStreams := allStreams[shard] + sort.Slice(shardStreams, func(i, j int) bool { + return shardStreams[i].ID < shardStreams[j].ID + }) + for _, stream := range shardStreams { logs = append(logs, fmt.Sprintf("id:%d;keyspace:%s;shard:%s;rules:%s;position:%v", stream.ID, stream.BinlogSource.Keyspace, stream.BinlogSource.Shard, stream.BinlogSource.Filter, stream.Position)) } @@ -247,7 +302,13 @@ func (dr *switcherDryRun) lockKeyspace(ctx context.Context, keyspace, _ string) func (dr *switcherDryRun) removeSourceTables(ctx context.Context, removalType TableRemovalType) error { logs := make([]string, 0) - for _, source := range dr.ts.Sources() { + sort.Strings(dr.ts.Tables()) // For deterministic output + sources := maps.Values(dr.ts.Sources()) + // Sort the slice for deterministic output. + sort.Slice(sources, func(i, j int) bool { + return sources[i].GetPrimary().Alias.Uid < sources[j].GetPrimary().Alias.Uid + }) + for _, source := range sources { for _, tableName := range dr.ts.Tables() { logs = append(logs, fmt.Sprintf("keyspace:%s;shard:%s;dbname:%s;tablet:%d;table:%s", source.GetPrimary().Keyspace, source.GetPrimary().Shard, source.GetPrimary().DbName(), source.GetPrimary().Alias.Uid, tableName)) @@ -267,7 +328,12 @@ func (dr *switcherDryRun) removeSourceTables(ctx context.Context, removalType Ta func (dr *switcherDryRun) dropSourceShards(ctx context.Context) error { logs := make([]string, 0) tabletsList := make(map[string][]string) - for _, si := range dr.ts.SourceShards() { + // Sort the slice for deterministic output. + sourceShards := dr.ts.SourceShards() + sort.Slice(sourceShards, func(i, j int) bool { + return sourceShards[i].PrimaryAlias.Uid < sourceShards[j].PrimaryAlias.Uid + }) + for _, si := range sourceShards { tabletAliases, err := dr.ts.TopoServer().FindAllTabletAliasesInShard(ctx, si.Keyspace(), si.ShardName()) if err != nil { return err @@ -276,7 +342,7 @@ func (dr *switcherDryRun) dropSourceShards(ctx context.Context) error { for _, t := range tabletAliases { tabletsList[si.ShardName()] = append(tabletsList[si.ShardName()], fmt.Sprintf("%d", t.Uid)) } - sort.Strings(tabletsList[si.ShardName()]) + sort.Strings(tabletsList[si.ShardName()]) // For deterministic output logs = append(logs, fmt.Sprintf("cell:%s;keyspace:%s;shards:[%s]", si.Shard.PrimaryAlias.Cell, si.Keyspace(), si.ShardName()), strings.Join(tabletsList[si.ShardName()], ",")) } @@ -293,7 +359,12 @@ func (dr *switcherDryRun) validateWorkflowHasCompleted(ctx context.Context) erro func (dr *switcherDryRun) dropTargetVReplicationStreams(ctx context.Context) error { logs := make([]string, 0) - for _, t := range dr.ts.Targets() { + // Sort the keys and slices for deterministic output. + targets := maps.Values(dr.ts.Targets()) + sort.Slice(targets, func(i, j int) bool { + return targets[i].GetPrimary().Alias.Uid < targets[j].GetPrimary().Alias.Uid + }) + for _, t := range targets { logs = append(logs, fmt.Sprintf("keyspace:%s;shard:%s;workflow:%s;dbname:%s;tablet:%d", t.GetShard().Keyspace(), t.GetShard().ShardName(), dr.ts.WorkflowName(), t.GetPrimary().DbName(), t.GetPrimary().Alias.Uid)) } @@ -303,7 +374,12 @@ func (dr *switcherDryRun) dropTargetVReplicationStreams(ctx context.Context) err func (dr *switcherDryRun) dropSourceReverseVReplicationStreams(ctx context.Context) error { logs := make([]string, 0) - for _, t := range dr.ts.Sources() { + sources := maps.Values(dr.ts.Sources()) + // Sort the slice for deterministic output. + sort.Slice(sources, func(i, j int) bool { + return sources[i].GetPrimary().Alias.Uid < sources[j].GetPrimary().Alias.Uid + }) + for _, t := range sources { logs = append(logs, fmt.Sprintf("keyspace:%s;shard:%s;workflow:%s;dbname:%s;tablet:%d", t.GetShard().Keyspace(), t.GetShard().ShardName(), ReverseWorkflowName(dr.ts.WorkflowName()), t.GetPrimary().DbName(), t.GetPrimary().Alias.Uid)) } @@ -313,7 +389,12 @@ func (dr *switcherDryRun) dropSourceReverseVReplicationStreams(ctx context.Conte func (dr *switcherDryRun) freezeTargetVReplication(ctx context.Context) error { logs := make([]string, 0) - for _, target := range dr.ts.Targets() { + // Sort the keys and slices for deterministic output. + targets := maps.Values(dr.ts.Targets()) + sort.Slice(targets, func(i, j int) bool { + return targets[i].GetPrimary().Alias.Uid < targets[j].GetPrimary().Alias.Uid + }) + for _, target := range targets { logs = append(logs, fmt.Sprintf("keyspace:%s;shard:%s;tablet:%d;workflow:%s;dbname:%s", target.GetPrimary().Keyspace, target.GetPrimary().Shard, target.GetPrimary().Alias.Uid, dr.ts.WorkflowName(), target.GetPrimary().DbName())) } @@ -325,7 +406,12 @@ func (dr *switcherDryRun) freezeTargetVReplication(ctx context.Context) error { func (dr *switcherDryRun) dropSourceDeniedTables(ctx context.Context) error { logs := make([]string, 0) - for _, si := range dr.ts.SourceShards() { + // Sort the slice for deterministic output. + sourceShards := dr.ts.SourceShards() + sort.Slice(sourceShards, func(i, j int) bool { + return sourceShards[i].PrimaryAlias.Uid < sourceShards[j].PrimaryAlias.Uid + }) + for _, si := range sourceShards { logs = append(logs, fmt.Sprintf("keyspace:%s;shard:%s;tablet:%d", si.Keyspace(), si.ShardName(), si.PrimaryAlias.Uid)) } if len(logs) > 0 { @@ -336,7 +422,12 @@ func (dr *switcherDryRun) dropSourceDeniedTables(ctx context.Context) error { func (dr *switcherDryRun) dropTargetDeniedTables(ctx context.Context) error { logs := make([]string, 0) - for _, si := range dr.ts.TargetShards() { + // Sort the slice for deterministic output. + targetShards := dr.ts.TargetShards() + sort.Slice(targetShards, func(i, j int) bool { + return targetShards[i].PrimaryAlias.Uid < targetShards[j].PrimaryAlias.Uid + }) + for _, si := range targetShards { logs = append(logs, fmt.Sprintf("keyspace:%s;shard:%s;tablet:%d", si.Keyspace(), si.ShardName(), si.PrimaryAlias.Uid)) } if len(logs) > 0 { @@ -351,7 +442,13 @@ func (dr *switcherDryRun) logs() *[]string { func (dr *switcherDryRun) removeTargetTables(ctx context.Context) error { logs := make([]string, 0) - for _, target := range dr.ts.Targets() { + sort.Strings(dr.ts.Tables()) // For deterministic output + // Sort the keys and slices for deterministic output. + targets := maps.Values(dr.ts.Targets()) + sort.Slice(targets, func(i, j int) bool { + return targets[i].GetPrimary().Alias.Uid < targets[j].GetPrimary().Alias.Uid + }) + for _, target := range targets { for _, tableName := range dr.ts.Tables() { logs = append(logs, fmt.Sprintf("keyspace:%s;shard:%s;dbname:%s;tablet:%d;table:%s", target.GetPrimary().Keyspace, target.GetPrimary().Shard, target.GetPrimary().DbName(), target.GetPrimary().Alias.Uid, tableName)) @@ -367,7 +464,13 @@ func (dr *switcherDryRun) removeTargetTables(ctx context.Context) error { func (dr *switcherDryRun) dropTargetShards(ctx context.Context) error { logs := make([]string, 0) tabletsList := make(map[string][]string) - for _, si := range dr.ts.TargetShards() { + sort.Strings(dr.ts.Tables()) // For deterministic output + // Sort the slice for deterministic output. + targetShards := dr.ts.TargetShards() + sort.Slice(targetShards, func(i, j int) bool { + return targetShards[i].PrimaryAlias.Uid < targetShards[j].PrimaryAlias.Uid + }) + for _, si := range targetShards { tabletAliases, err := dr.ts.TopoServer().FindAllTabletAliasesInShard(ctx, si.Keyspace(), si.ShardName()) if err != nil { return err @@ -376,7 +479,7 @@ func (dr *switcherDryRun) dropTargetShards(ctx context.Context) error { for _, t := range tabletAliases { tabletsList[si.ShardName()] = append(tabletsList[si.ShardName()], fmt.Sprintf("%d", t.Uid)) } - sort.Strings(tabletsList[si.ShardName()]) + sort.Strings(tabletsList[si.ShardName()]) // For deterministic output logs = append(logs, fmt.Sprintf("cell:%s;keyspace:%s;shards:[%s]", si.Shard.PrimaryAlias.Cell, si.Keyspace(), si.ShardName()), strings.Join(tabletsList[si.ShardName()], ",")) } @@ -401,6 +504,7 @@ func (dr *switcherDryRun) resetSequences(ctx context.Context) error { } func (dr *switcherDryRun) initializeTargetSequences(ctx context.Context, sequencesByBackingTable map[string]*sequenceMetadata) error { + // Sort keys for deterministic output. sortedBackingTableNames := maps.Keys(sequencesByBackingTable) slices.Sort(sortedBackingTableNames) dr.drLog.Log(fmt.Sprintf("The following sequence backing tables used by tables being moved will be initialized: %s", diff --git a/go/vt/vtctl/workflow/traffic_switcher.go b/go/vt/vtctl/workflow/traffic_switcher.go index 9ea1c8b609b..42f097f35b0 100644 --- a/go/vt/vtctl/workflow/traffic_switcher.go +++ b/go/vt/vtctl/workflow/traffic_switcher.go @@ -26,12 +26,11 @@ import ( "sync" "time" - vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" - "golang.org/x/exp/maps" "golang.org/x/sync/errgroup" "vitess.io/vitess/go/json2" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/sqlescape" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" @@ -53,6 +52,7 @@ import ( tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vschemapb "vitess.io/vitess/go/vt/proto/vschema" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) @@ -104,6 +104,13 @@ const ( // TrafficSwitchDirection specifies the switching direction. type TrafficSwitchDirection int +func (tsd TrafficSwitchDirection) String() string { + if tsd == DirectionForward { + return "forward" + } + return "backward" +} + // TableRemovalType specifies the way the a table will be removed during a // DropSource for a MoveTables workflow. type TableRemovalType int @@ -428,6 +435,10 @@ func (ts *trafficSwitcher) deleteShardRoutingRules(ctx context.Context) error { } srr, err := topotools.GetShardRoutingRules(ctx, ts.TopoServer()) if err != nil { + if topo.IsErrType(err, topo.NoNode) { + log.Warningf("No shard routing rules found when attempting to delete the ones for the %s keyspace", ts.targetKeyspace) + return nil + } return err } for _, si := range ts.TargetShards() { @@ -520,14 +531,14 @@ func (ts *trafficSwitcher) removeSourceTables(ctx context.Context, removalType T query := fmt.Sprintf("drop table %s.%s", primaryDbName, tableNameEscaped) if removalType == DropTable { ts.Logger().Infof("%s: Dropping table %s.%s\n", - source.GetPrimary().String(), source.GetPrimary().DbName(), tableName) + topoproto.TabletAliasString(source.GetPrimary().GetAlias()), source.GetPrimary().DbName(), tableName) } else { renameName, err := sqlescape.EnsureEscaped(getRenameFileName(tableName)) if err != nil { return err } ts.Logger().Infof("%s: Renaming table %s.%s to %s.%s\n", - source.GetPrimary().String(), source.GetPrimary().DbName(), tableName, source.GetPrimary().DbName(), renameName) + topoproto.TabletAliasString(source.GetPrimary().GetAlias()), source.GetPrimary().DbName(), tableName, source.GetPrimary().DbName(), renameName) query = fmt.Sprintf("rename table %s.%s TO %s.%s", primaryDbName, tableNameEscaped, primaryDbName, renameName) } _, err = ts.ws.tmc.ExecuteFetchAsDba(ctx, source.GetPrimary().Tablet, false, &tabletmanagerdatapb.ExecuteFetchAsDbaRequest{ @@ -537,10 +548,14 @@ func (ts *trafficSwitcher) removeSourceTables(ctx context.Context, removalType T DisableForeignKeyChecks: true, }) if err != nil { - ts.Logger().Errorf("%s: Error removing table %s: %v", source.GetPrimary().String(), tableName, err) + if mysqlErr, ok := err.(*sqlerror.SQLError); ok && mysqlErr.Num == sqlerror.ERNoSuchTable { + ts.Logger().Warningf("%s: Table %s did not exist when attempting to remove it", topoproto.TabletAliasString(source.GetPrimary().GetAlias()), tableName) + return nil + } + ts.Logger().Errorf("%s: Error removing table %s: %v", topoproto.TabletAliasString(source.GetPrimary().GetAlias()), tableName, err) return err } - ts.Logger().Infof("%s: Removed table %s.%s\n", source.GetPrimary().String(), source.GetPrimary().DbName(), tableName) + ts.Logger().Infof("%s: Removed table %s.%s\n", topoproto.TabletAliasString(source.GetPrimary().GetAlias()), source.GetPrimary().DbName(), tableName) } return nil @@ -598,7 +613,7 @@ func (ts *trafficSwitcher) switchShardReads(ctx context.Context, cells []string, } func (ts *trafficSwitcher) switchTableReads(ctx context.Context, cells []string, servedTypes []topodatapb.TabletType, rebuildSrvVSchema bool, direction TrafficSwitchDirection) error { - log.Infof("switchTableReads: cells: %s, tablet types: %+v, direction %d", strings.Join(cells, ","), servedTypes, direction) + log.Infof("switchTableReads: cells: %s, tablet types: %+v, direction: %s", strings.Join(cells, ","), servedTypes, direction) rules, err := topotools.GetRoutingRules(ctx, ts.TopoServer()) if err != nil { return err @@ -615,11 +630,6 @@ func (ts *trafficSwitcher) switchTableReads(ctx context.Context, cells []string, tt := strings.ToLower(servedType.String()) for _, table := range ts.Tables() { - if direction == DirectionForward { - log.Infof("Route direction forward") - } else { - log.Infof("Route direction backwards") - } toTarget := []string{ts.TargetKeyspaceName() + "." + table} rules[table+"@"+tt] = toTarget rules[ts.TargetKeyspaceName()+"."+table+"@"+tt] = toTarget @@ -639,7 +649,7 @@ func (ts *trafficSwitcher) startReverseVReplication(ctx context.Context) error { return ts.ForAllSources(func(source *MigrationSource) error { query := fmt.Sprintf("update _vt.vreplication set state='Running', message='' where db_name=%s and workflow=%s", encodeString(source.GetPrimary().DbName()), encodeString(ts.ReverseWorkflowName())) - _, err := ts.VReplicationExec(ctx, source.GetPrimary().Alias, query) + _, err := ts.VReplicationExec(ctx, source.GetPrimary().GetAlias(), query) return err }) } @@ -704,25 +714,11 @@ func (ts *trafficSwitcher) changeShardsAccess(ctx context.Context, keyspace stri func (ts *trafficSwitcher) allowTargetWrites(ctx context.Context) error { if ts.MigrationType() == binlogdatapb.MigrationType_TABLES { - return ts.allowTableTargetWrites(ctx) + return ts.switchDeniedTables(ctx) } return ts.changeShardsAccess(ctx, ts.TargetKeyspaceName(), ts.TargetShards(), allowWrites) } -func (ts *trafficSwitcher) allowTableTargetWrites(ctx context.Context) error { - return ts.ForAllTargets(func(target *MigrationTarget) error { - if _, err := ts.TopoServer().UpdateShardFields(ctx, ts.TargetKeyspaceName(), target.GetShard().ShardName(), func(si *topo.ShardInfo) error { - return si.UpdateDeniedTables(ctx, topodatapb.TabletType_PRIMARY, nil, true, ts.Tables()) - }); err != nil { - return err - } - rtbsCtx, cancel := context.WithTimeout(ctx, shardTabletRefreshTimeout) - defer cancel() - _, _, err := topotools.RefreshTabletsByShard(rtbsCtx, ts.TopoServer(), ts.TabletManagerClient(), target.GetShard(), nil, ts.Logger()) - return err - }) -} - func (ts *trafficSwitcher) changeRouting(ctx context.Context) error { if ts.MigrationType() == binlogdatapb.MigrationType_TABLES { return ts.changeWriteRoute(ctx) @@ -833,6 +829,7 @@ func (ts *trafficSwitcher) deleteReverseVReplication(ctx context.Context) error return ts.ForAllSources(func(source *MigrationSource) error { query := fmt.Sprintf(sqlDeleteWorkflow, encodeString(source.GetPrimary().DbName()), encodeString(ts.reverseWorkflow)) if _, err := ts.TabletManagerClient().VReplicationExec(ctx, source.GetPrimary().Tablet, query); err != nil { + // vreplication.exec returns no error on delete if the rows do not exist. return err } ts.ws.deleteWorkflowVDiffData(ctx, source.GetPrimary().Tablet, ts.reverseWorkflow) @@ -926,8 +923,8 @@ func (ts *trafficSwitcher) createReverseVReplication(ctx context.Context) error }) } log.Infof("Creating reverse workflow vreplication stream on tablet %s: workflow %s, startPos %s", - source.GetPrimary().Alias, ts.ReverseWorkflowName(), target.Position) - _, err = ts.VReplicationExec(ctx, source.GetPrimary().Alias, + source.GetPrimary().GetAlias(), ts.ReverseWorkflowName(), target.Position) + _, err = ts.VReplicationExec(ctx, source.GetPrimary().GetAlias(), binlogplayer.CreateVReplicationState(ts.ReverseWorkflowName(), reverseBls, target.Position, binlogdatapb.VReplicationWorkflowState_Stopped, source.GetPrimary().DbName(), ts.workflowType, ts.workflowSubType)) if err != nil { @@ -939,11 +936,11 @@ func (ts *trafficSwitcher) createReverseVReplication(ctx context.Context) error if err != nil { return err } - updateQuery := ts.getReverseVReplicationUpdateQuery(target.GetPrimary().Alias.Cell, - source.GetPrimary().Alias.Cell, source.GetPrimary().DbName(), string(optionsJSON)) + updateQuery := ts.getReverseVReplicationUpdateQuery(target.GetPrimary().GetAlias().GetCell(), + source.GetPrimary().GetAlias().GetCell(), source.GetPrimary().DbName(), string(optionsJSON)) if updateQuery != "" { - log.Infof("Updating vreplication stream entry on %s with: %s", source.GetPrimary().Alias, updateQuery) - _, err = ts.VReplicationExec(ctx, source.GetPrimary().Alias, updateQuery) + log.Infof("Updating vreplication stream entry on %s with: %s", source.GetPrimary().GetAlias(), updateQuery) + _, err = ts.VReplicationExec(ctx, source.GetPrimary().GetAlias(), updateQuery) return err } return nil @@ -984,7 +981,7 @@ func (ts *trafficSwitcher) waitForCatchup(ctx context.Context, filteredReplicati // Source writes have been stopped, wait for all streams on targets to catch up. if err := ts.ForAllUIDs(func(target *MigrationTarget, uid int32) error { ts.Logger().Infof("Before Catchup: uid: %d, target primary %s, target position %s, shard %s", uid, - target.GetPrimary().AliasString(), target.Position, target.GetShard().String()) + topoproto.TabletAliasString(target.GetPrimary().GetAlias()), target.Position, target.GetShard().String()) bls := target.Sources[uid] source := ts.Sources()[bls.Shard] ts.Logger().Infof("Before Catchup: waiting for keyspace:shard: %v:%v to reach source position %v, uid %d", @@ -997,7 +994,7 @@ func (ts *trafficSwitcher) waitForCatchup(ctx context.Context, filteredReplicati ts.Logger().Infof("After catchup: position for keyspace:shard: %v:%v reached, uid %d", ts.TargetKeyspaceName(), target.GetShard().ShardName(), uid) if _, err := ts.TabletManagerClient().VReplicationExec(ctx, target.GetPrimary().Tablet, binlogplayer.StopVReplication(uid, "stopped for cutover")); err != nil { - log.Infof("Error marking stopped for cutover on %s, uid %d", target.GetPrimary().AliasString(), uid) + log.Infof("Error marking stopped for cutover on %s, uid %d", topoproto.TabletAliasString(target.GetPrimary().GetAlias()), uid) return err } return nil @@ -1008,7 +1005,7 @@ func (ts *trafficSwitcher) waitForCatchup(ctx context.Context, filteredReplicati return ts.ForAllTargets(func(target *MigrationTarget) error { var err error target.Position, err = ts.TabletManagerClient().PrimaryPosition(ctx, target.GetPrimary().Tablet) - ts.Logger().Infof("After catchup, position for target primary %s, %v", target.GetPrimary().AliasString(), target.Position) + ts.Logger().Infof("After catchup, position for target primary %s, %v", topoproto.TabletAliasString(target.GetPrimary().GetAlias()), target.Position) return err }) } @@ -1016,7 +1013,7 @@ func (ts *trafficSwitcher) waitForCatchup(ctx context.Context, filteredReplicati func (ts *trafficSwitcher) stopSourceWrites(ctx context.Context) error { var err error if ts.MigrationType() == binlogdatapb.MigrationType_TABLES { - err = ts.changeTableSourceWrites(ctx, disallowWrites) + err = ts.switchDeniedTables(ctx) } else { err = ts.changeShardsAccess(ctx, ts.SourceKeyspaceName(), ts.SourceShards(), disallowWrites) } @@ -1036,36 +1033,60 @@ func (ts *trafficSwitcher) stopSourceWrites(ctx context.Context) error { }) } -func (ts *trafficSwitcher) changeTableSourceWrites(ctx context.Context, access accessType) error { - err := ts.ForAllSources(func(source *MigrationSource) error { - if _, err := ts.TopoServer().UpdateShardFields(ctx, ts.SourceKeyspaceName(), source.GetShard().ShardName(), func(si *topo.ShardInfo) error { - return si.UpdateDeniedTables(ctx, topodatapb.TabletType_PRIMARY, nil, access == allowWrites /* remove */, ts.Tables()) - }); err != nil { +// switchDeniedTables switches the denied tables rules for the traffic switch. +// They are removed on the source side and added on the target side. +func (ts *trafficSwitcher) switchDeniedTables(ctx context.Context) error { + if ts.MigrationType() != binlogdatapb.MigrationType_TABLES { + return nil + } + + egrp, ectx := errgroup.WithContext(ctx) + egrp.Go(func() error { + return ts.ForAllSources(func(source *MigrationSource) error { + if _, err := ts.TopoServer().UpdateShardFields(ctx, ts.SourceKeyspaceName(), source.GetShard().ShardName(), func(si *topo.ShardInfo) error { + return si.UpdateDeniedTables(ectx, topodatapb.TabletType_PRIMARY, nil, false, ts.Tables()) + }); err != nil { + return err + } + rtbsCtx, cancel := context.WithTimeout(ectx, shardTabletRefreshTimeout) + defer cancel() + isPartial, partialDetails, err := topotools.RefreshTabletsByShard(rtbsCtx, ts.TopoServer(), ts.TabletManagerClient(), source.GetShard(), nil, ts.Logger()) + if isPartial { + err = fmt.Errorf("failed to successfully refresh all tablets in the %s/%s source shard (%v):\n %v", + source.GetShard().Keyspace(), source.GetShard().ShardName(), err, partialDetails) + } return err - } - rtbsCtx, cancel := context.WithTimeout(ctx, shardTabletRefreshTimeout) - defer cancel() - isPartial, partialDetails, err := topotools.RefreshTabletsByShard(rtbsCtx, ts.TopoServer(), ts.TabletManagerClient(), source.GetShard(), nil, ts.Logger()) - if isPartial { - err = fmt.Errorf("failed to successfully refresh all tablets in the %s/%s source shard (%v):\n %v", - source.GetShard().Keyspace(), source.GetShard().ShardName(), err, partialDetails) - } - return err + }) }) - if err != nil { - log.Warningf("Error in changeTableSourceWrites: %s", err) + egrp.Go(func() error { + return ts.ForAllTargets(func(target *MigrationTarget) error { + if _, err := ts.TopoServer().UpdateShardFields(ectx, ts.TargetKeyspaceName(), target.GetShard().ShardName(), func(si *topo.ShardInfo) error { + return si.UpdateDeniedTables(ctx, topodatapb.TabletType_PRIMARY, nil, true, ts.Tables()) + }); err != nil { + return err + } + rtbsCtx, cancel := context.WithTimeout(ectx, shardTabletRefreshTimeout) + defer cancel() + isPartial, partialDetails, err := topotools.RefreshTabletsByShard(rtbsCtx, ts.TopoServer(), ts.TabletManagerClient(), target.GetShard(), nil, ts.Logger()) + if isPartial { + err = fmt.Errorf("failed to successfully refresh all tablets in the %s/%s target shard (%v):\n %v", + target.GetShard().Keyspace(), target.GetShard().ShardName(), err, partialDetails) + } + return err + }) + }) + if err := egrp.Wait(); err != nil { + log.Warningf("Error in switchDeniedTables: %s", err) return err } - // Note that the denied tables, which are being updated in this method, are not part of the SrvVSchema in the topo. - // However, we are using the notification of a SrvVSchema change in VTGate to recompute the state of a - // MoveTables workflow (which also looks up denied tables from the topo). So we need to trigger a SrvVSchema change here. - return ts.TopoServer().RebuildSrvVSchema(ctx, nil) + + return nil } func (ts *trafficSwitcher) cancelMigration(ctx context.Context, sm *StreamMigrator) { var err error if ts.MigrationType() == binlogdatapb.MigrationType_TABLES { - err = ts.changeTableSourceWrites(ctx, allowWrites) + err = ts.switchDeniedTables(ctx) } else { err = ts.changeShardsAccess(ctx, ts.SourceKeyspaceName(), ts.SourceShards(), allowWrites) } @@ -1087,7 +1108,7 @@ func (ts *trafficSwitcher) cancelMigration(ctx context.Context, sm *StreamMigrat err = ts.deleteReverseVReplication(ctx) if err != nil { - ts.Logger().Errorf("Cancel migration failed: could not delete revers vreplication entries: %v", err) + ts.Logger().Errorf("Cancel migration failed: could not delete reverse vreplication streams: %v", err) } } @@ -1112,6 +1133,7 @@ func (ts *trafficSwitcher) dropTargetVReplicationStreams(ctx context.Context) er ts.Logger().Infof("Deleting target streams and related data for workflow %s db_name %s", ts.WorkflowName(), target.GetPrimary().DbName()) query := fmt.Sprintf(sqlDeleteWorkflow, encodeString(target.GetPrimary().DbName()), encodeString(ts.WorkflowName())) if _, err := ts.TabletManagerClient().VReplicationExec(ctx, target.GetPrimary().Tablet, query); err != nil { + // vreplication.exec returns no error on delete if the rows do not exist. return err } ts.ws.deleteWorkflowVDiffData(ctx, target.GetPrimary().Tablet, ts.WorkflowName()) @@ -1125,6 +1147,7 @@ func (ts *trafficSwitcher) dropSourceReverseVReplicationStreams(ctx context.Cont ts.Logger().Infof("Deleting reverse streams and related data for workflow %s db_name %s", ts.WorkflowName(), source.GetPrimary().DbName()) query := fmt.Sprintf(sqlDeleteWorkflow, encodeString(source.GetPrimary().DbName()), encodeString(ReverseWorkflowName(ts.WorkflowName()))) if _, err := ts.TabletManagerClient().VReplicationExec(ctx, source.GetPrimary().Tablet, query); err != nil { + // vreplication.exec returns no error on delete if the rows do not exist. return err } ts.ws.deleteWorkflowVDiffData(ctx, source.GetPrimary().Tablet, ReverseWorkflowName(ts.WorkflowName())) @@ -1147,7 +1170,7 @@ func (ts *trafficSwitcher) removeTargetTables(ctx context.Context) error { } query := fmt.Sprintf("drop table %s.%s", primaryDbName, tableName) ts.Logger().Infof("%s: Dropping table %s.%s\n", - target.GetPrimary().String(), target.GetPrimary().DbName(), tableName) + topoproto.TabletAliasString(target.GetPrimary().GetAlias()), target.GetPrimary().DbName(), tableName) res, err := ts.ws.tmc.ExecuteFetchAsDba(ctx, target.GetPrimary().Tablet, false, &tabletmanagerdatapb.ExecuteFetchAsDbaRequest{ Query: []byte(query), MaxRows: 1, @@ -1156,12 +1179,16 @@ func (ts *trafficSwitcher) removeTargetTables(ctx context.Context) error { }) log.Infof("Removed target table with result: %+v", res) if err != nil { - ts.Logger().Errorf("%s: Error removing table %s: %v", - target.GetPrimary().String(), tableName, err) + if mysqlErr, ok := err.(*sqlerror.SQLError); ok && mysqlErr.Num == sqlerror.ERNoSuchTable { + // The table was already gone, so we can ignore the error. + ts.Logger().Warningf("%s: Table %s did not exist when attempting to remove it", topoproto.TabletAliasString(target.GetPrimary().GetAlias()), tableName) + return nil + } + ts.Logger().Errorf("%s: Error removing table %s: %v", topoproto.TabletAliasString(target.GetPrimary().GetAlias()), tableName, err) return err } ts.Logger().Infof("%s: Removed table %s.%s\n", - target.GetPrimary().String(), target.GetPrimary().DbName(), tableName) + topoproto.TabletAliasString(target.GetPrimary().GetAlias()), target.GetPrimary().DbName(), tableName) } return nil @@ -1626,7 +1653,7 @@ func (ts *trafficSwitcher) resetSequences(ctx context.Context) error { } return ts.ForAllSources(func(source *MigrationSource) error { ts.Logger().Infof("Resetting sequences for source shard %s.%s on tablet %s", - source.GetShard().Keyspace(), source.GetShard().ShardName(), source.GetPrimary().String()) + source.GetShard().Keyspace(), source.GetShard().ShardName(), topoproto.TabletAliasString(source.GetPrimary().GetAlias())) return ts.TabletManagerClient().ResetSequences(ctx, source.GetPrimary().Tablet, ts.Tables()) }) } diff --git a/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go b/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go index 42e5129b40e..789319a2a53 100644 --- a/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go @@ -412,6 +412,13 @@ func TestMoveTables(t *testing.T) { ), fmt.Sprintf("%d|%s|%s|NULL|0|0|||1686577659|0|Stopped||%s|1||0|0|0||0|1", vreplID, bls, position, targetKs), ), nil) + ftc.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflow, wf, tenv.dbName), sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "id|source|pos|stop_pos|max_tps|max_replication_lag|cell|tablet_types|time_updated|transaction_timestamp|state|message|db_name|rows_copied|tags|time_heartbeat|workflow_type|time_throttled|component_throttled|workflow_sub_type|defer_secondary_keys", + "int64|varchar|blob|varchar|int64|int64|varchar|varchar|int64|int64|varchar|varchar|varchar|int64|varchar|int64|int64|int64|varchar|int64|int64", + ), + fmt.Sprintf("%d|%s|%s|NULL|0|0|||1686577659|0|Stopped||%s|1||0|0|0||0|1", vreplID, bls, position, targetKs), + ), nil) ftc.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflowConfig, wf), sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id|source|cell|tablet_types|state|message", From 999001bff8a77f0a3d4995ccbdab2382dcabf603 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 12 Jun 2024 21:02:57 +0530 Subject: [PATCH 24/40] fix: order by subquery planning (#16049) Signed-off-by: Andres Taylor Signed-off-by: Harshit Gangal Signed-off-by: Florent Poinsard Co-authored-by: Andres Taylor Co-authored-by: Florent Poinsard --- .../vtgate/queries/subquery/schema.sql | 18 +++- .../vtgate/queries/subquery/subquery_test.go | 44 +++++++++ .../vtgate/queries/subquery/vschema.json | 31 ++++++ go/vt/sqlparser/ast.go | 47 +++++++++ go/vt/sqlparser/ast_funcs.go | 9 ++ go/vt/vtgate/planbuilder/fuzz.go | 4 +- .../operators/aggregation_pushing.go | 21 ++-- .../planbuilder/operators/aggregator.go | 40 +++++++- go/vt/vtgate/planbuilder/operators/helpers.go | 10 +- .../operators/horizon_expanding.go | 65 ++++++++---- .../planbuilder/operators/projection.go | 25 +++-- .../planbuilder/operators/query_planning.go | 98 ++++++++++++------- .../planbuilder/operators/queryprojection.go | 17 +++- .../vtgate/planbuilder/operators/subquery.go | 31 ++++-- .../planbuilder/operators/subquery_builder.go | 4 +- .../operators/subquery_container.go | 12 ++- .../operators/subquery_planning.go | 34 ++++++- go/vt/vtgate/planbuilder/plan_test.go | 3 +- go/vt/vtgate/planbuilder/planner_test.go | 3 +- .../planbuilder/predicate_rewrite_test.go | 1 - go/vt/vtgate/planbuilder/rewrite_test.go | 3 +- go/vt/vtgate/planbuilder/set.go | 14 +-- go/vt/vtgate/planbuilder/show_test.go | 6 +- .../planbuilder/testdata/select_cases.json | 70 ++++++------- go/vt/vtgate/planbuilder/vexplain.go | 3 +- go/vt/vtgate/planbuilder/vindex_func.go | 3 +- go/vt/vtgate/planbuilder/vstream.go | 3 +- 27 files changed, 459 insertions(+), 160 deletions(-) diff --git a/go/test/endtoend/vtgate/queries/subquery/schema.sql b/go/test/endtoend/vtgate/queries/subquery/schema.sql index a64ac799a4e..9dfa963d340 100644 --- a/go/test/endtoend/vtgate/queries/subquery/schema.sql +++ b/go/test/endtoend/vtgate/queries/subquery/schema.sql @@ -4,18 +4,21 @@ create table t1 id2 bigint, primary key (id1) ) Engine = InnoDB; + create table t1_id2_idx ( id2 bigint, keyspace_id varbinary(10), primary key (id2) ) Engine = InnoDB; + create table t2 ( id3 bigint, id4 bigint, primary key (id3) ) Engine = InnoDB; + create table t2_id4_idx ( id bigint not null auto_increment, @@ -23,4 +26,17 @@ create table t2_id4_idx id3 bigint, primary key (id), key idx_id4 (id4) -) Engine = InnoDB; \ No newline at end of file +) Engine = InnoDB; + +CREATE TABLE user +( + id INT PRIMARY KEY, + name VARCHAR(100) +); + +CREATE TABLE user_extra +( + user_id INT, + extra_info VARCHAR(100), + PRIMARY KEY (user_id, extra_info) +); \ No newline at end of file diff --git a/go/test/endtoend/vtgate/queries/subquery/subquery_test.go b/go/test/endtoend/vtgate/queries/subquery/subquery_test.go index 59dc42de060..abbf5ff15e8 100644 --- a/go/test/endtoend/vtgate/queries/subquery/subquery_test.go +++ b/go/test/endtoend/vtgate/queries/subquery/subquery_test.go @@ -17,6 +17,7 @@ limitations under the License. package subquery import ( + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -188,3 +189,46 @@ func TestSubqueryInDerivedTable(t *testing.T) { mcmp.Exec(`select t.a from (select t1.id2, t2.id3, (select id2 from t1 order by id2 limit 1) as a from t1 join t2 on t1.id1 = t2.id4) t`) mcmp.Exec(`SELECT COUNT(*) FROM (SELECT DISTINCT t1.id1 FROM t1 JOIN t2 ON t1.id1 = t2.id4) dt`) } + +func TestSubqueries(t *testing.T) { + // This method tests many types of subqueries. The queries should move to a vitess-tester test file once we have a way to run them. + // The commented out queries are failing because of wrong types being returned. + // The tests are commented out until the issue is fixed. + utils.SkipIfBinaryIsBelowVersion(t, 21, "vtgate") + mcmp, closer := start(t) + defer closer() + queries := []string{ + `INSERT INTO user (id, name) VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie'), (4, 'David'), (5, 'Eve'), (6, 'Frank'), (7, 'Grace'), (8, 'Hannah'), (9, 'Ivy'), (10, 'Jack')`, + `INSERT INTO user_extra (user_id, extra_info) VALUES (1, 'info1'), (1, 'info2'), (2, 'info1'), (3, 'info1'), (3, 'info2'), (4, 'info1'), (5, 'info1'), (6, 'info1'), (7, 'info1'), (8, 'info1')`, + `SELECT (SELECT COUNT(*) FROM user_extra) AS order_count, id FROM user WHERE id = (SELECT COUNT(*) FROM user_extra)`, + `SELECT id, (SELECT COUNT(*) FROM user_extra) AS order_count FROM user ORDER BY (SELECT COUNT(*) FROM user_extra)`, + `SELECT id FROM user WHERE id = (SELECT COUNT(*) FROM user_extra) ORDER BY (SELECT COUNT(*) FROM user_extra)`, + `SELECT (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id) AS extra_count, id, name FROM user WHERE (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id) > 0`, + `SELECT id, name, (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id) AS extra_count FROM user ORDER BY (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id)`, + `SELECT id, name FROM user WHERE (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id) > 0 ORDER BY (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id)`, + `SELECT id, name, (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id) AS extra_count FROM user GROUP BY id, name HAVING COUNT(*) > (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id)`, + `SELECT id, name, COUNT(*) FROM user WHERE (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id) > 0 GROUP BY id, name HAVING COUNT(*) > (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id)`, + `SELECT id, round(MAX(id + (SELECT COUNT(*) FROM user_extra where user_id = 42))) as r FROM user WHERE id = 42 GROUP BY id ORDER BY r`, + `SELECT id, name, (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id) * 2 AS double_extra_count FROM user`, + `SELECT id, name FROM user WHERE id IN (SELECT user_id FROM user_extra WHERE LENGTH(extra_info) > 4)`, + `SELECT id, COUNT(*) FROM user GROUP BY id HAVING COUNT(*) > (SELECT COUNT(*) FROM user_extra WHERE user_extra.user_id = user.id) + 1`, + `SELECT id, name FROM user ORDER BY (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id) * id`, + `SELECT id, name, (SELECT COUNT(*) FROM user_extra WHERE user.id = user_extra.user_id) + id AS extra_count_plus_id FROM user`, + `SELECT id, name FROM user WHERE id IN (SELECT user_id FROM user_extra WHERE extra_info = 'info1') OR id IN (SELECT user_id FROM user_extra WHERE extra_info = 'info2')`, + `SELECT id, name, (SELECT COUNT(*) FROM user_extra) AS total_extra_count, SUM(id) AS sum_ids FROM user GROUP BY id, name ORDER BY (SELECT COUNT(*) FROM user_extra)`, + // `SELECT id, name, (SELECT SUM(LENGTH(extra_info)) FROM user_extra) AS total_length_extra_info, AVG(id) AS avg_ids FROM user GROUP BY id, name HAVING (SELECT SUM(LENGTH(extra_info)) FROM user_extra) > 10`, + `SELECT id, name, (SELECT AVG(LENGTH(extra_info)) FROM user_extra) AS avg_length_extra_info, MAX(id) AS max_id FROM user WHERE id IN (SELECT user_id FROM user_extra) GROUP BY id, name`, + `SELECT id, name, (SELECT MAX(LENGTH(extra_info)) FROM user_extra) AS max_length_extra_info, MIN(id) AS min_id FROM user GROUP BY id, name ORDER BY (SELECT MAX(LENGTH(extra_info)) FROM user_extra)`, + `SELECT id, name, (SELECT MIN(LENGTH(extra_info)) FROM user_extra) AS min_length_extra_info, SUM(id) AS sum_ids FROM user GROUP BY id, name HAVING (SELECT MIN(LENGTH(extra_info)) FROM user_extra) < 5`, + `SELECT id, name, (SELECT COUNT(*) FROM user_extra) AS total_extra_count, AVG(id) AS avg_ids FROM user WHERE id > (SELECT COUNT(*) FROM user_extra) GROUP BY id, name`, + // `SELECT id, name, (SELECT SUM(LENGTH(extra_info)) FROM user_extra) AS total_length_extra_info, COUNT(id) AS count_ids FROM user GROUP BY id, name ORDER BY (SELECT SUM(LENGTH(extra_info)) FROM user_extra)`, + // `SELECT id, name, (SELECT COUNT(*) FROM user_extra) AS total_extra_count, (SELECT SUM(LENGTH(extra_info)) FROM user_extra) AS total_length_extra_info, (SELECT AVG(LENGTH(extra_info)) FROM user_extra) AS avg_length_extra_info, (SELECT MAX(LENGTH(extra_info)) FROM user_extra) AS max_length_extra_info, (SELECT MIN(LENGTH(extra_info)) FROM user_extra) AS min_length_extra_info, SUM(id) AS sum_ids FROM user GROUP BY id, name HAVING (SELECT AVG(LENGTH(extra_info)) FROM user_extra) > 2`, + `SELECT id, name, (SELECT COUNT(*) FROM user_extra) + id AS total_extra_count_plus_id, AVG(id) AS avg_ids FROM user WHERE id < (SELECT MAX(user_id) FROM user_extra) GROUP BY id, name`, + } + + for idx, query := range queries { + mcmp.Run(fmt.Sprintf("%d %s", idx, query), func(mcmp *utils.MySQLCompare) { + mcmp.Exec(query) + }) + } +} diff --git a/go/test/endtoend/vtgate/queries/subquery/vschema.json b/go/test/endtoend/vtgate/queries/subquery/vschema.json index da4e589f20f..a98255db65e 100644 --- a/go/test/endtoend/vtgate/queries/subquery/vschema.json +++ b/go/test/endtoend/vtgate/queries/subquery/vschema.json @@ -22,6 +22,9 @@ "autocommit": "true" }, "owner": "t2" + }, + "xxhash": { + "type": "xxhash" } }, "tables": { @@ -64,6 +67,34 @@ "name": "hash" } ] + }, + "user_extra": { + "name": "user_extra", + "column_vindexes": [ + { + "columns": [ + "user_id", + "extra_info" + ], + "type": "xxhash", + "name": "xxhash", + "vindex": null + } + ] + }, + "user": { + "name": "user", + "column_vindexes": [ + { + "columns": [ + "id" + ], + "type": "xxhash", + "name": "xxhash", + "vindex": null + } + ] } + } } \ No newline at end of file diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index 4e96a3ea372..76beb368943 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -2878,6 +2878,8 @@ type ( Expr GetArg() Expr GetArgs() Exprs + SetArg(expr Expr) + SetArgs(exprs Exprs) error // AggrName returns the lower case string representing this aggregation function AggrName() string } @@ -3405,6 +3407,51 @@ func (varS *VarSamp) GetArgs() Exprs { return Exprs{varS.Arg} } func (variance *Variance) GetArgs() Exprs { return Exprs{variance.Arg} } func (av *AnyValue) GetArgs() Exprs { return Exprs{av.Arg} } +func (min *Min) SetArg(expr Expr) { min.Arg = expr } +func (sum *Sum) SetArg(expr Expr) { sum.Arg = expr } +func (max *Max) SetArg(expr Expr) { max.Arg = expr } +func (avg *Avg) SetArg(expr Expr) { avg.Arg = expr } +func (*CountStar) SetArg(expr Expr) {} +func (count *Count) SetArg(expr Expr) { count.Args = Exprs{expr} } +func (grpConcat *GroupConcatExpr) SetArg(expr Expr) { grpConcat.Exprs = Exprs{expr} } +func (bAnd *BitAnd) SetArg(expr Expr) { bAnd.Arg = expr } +func (bOr *BitOr) SetArg(expr Expr) { bOr.Arg = expr } +func (bXor *BitXor) SetArg(expr Expr) { bXor.Arg = expr } +func (std *Std) SetArg(expr Expr) { std.Arg = expr } +func (stdD *StdDev) SetArg(expr Expr) { stdD.Arg = expr } +func (stdP *StdPop) SetArg(expr Expr) { stdP.Arg = expr } +func (stdS *StdSamp) SetArg(expr Expr) { stdS.Arg = expr } +func (varP *VarPop) SetArg(expr Expr) { varP.Arg = expr } +func (varS *VarSamp) SetArg(expr Expr) { varS.Arg = expr } +func (variance *Variance) SetArg(expr Expr) { variance.Arg = expr } +func (av *AnyValue) SetArg(expr Expr) { av.Arg = expr } + +func (min *Min) SetArgs(exprs Exprs) error { return setFuncArgs(min, exprs, "MIN") } +func (sum *Sum) SetArgs(exprs Exprs) error { return setFuncArgs(sum, exprs, "SUM") } +func (max *Max) SetArgs(exprs Exprs) error { return setFuncArgs(max, exprs, "MAX") } +func (avg *Avg) SetArgs(exprs Exprs) error { return setFuncArgs(avg, exprs, "AVG") } +func (*CountStar) SetArgs(Exprs) error { return nil } +func (bAnd *BitAnd) SetArgs(exprs Exprs) error { return setFuncArgs(bAnd, exprs, "BIT_AND") } +func (bOr *BitOr) SetArgs(exprs Exprs) error { return setFuncArgs(bOr, exprs, "BIT_OR") } +func (bXor *BitXor) SetArgs(exprs Exprs) error { return setFuncArgs(bXor, exprs, "BIT_XOR") } +func (std *Std) SetArgs(exprs Exprs) error { return setFuncArgs(std, exprs, "STD") } +func (stdD *StdDev) SetArgs(exprs Exprs) error { return setFuncArgs(stdD, exprs, "STDDEV") } +func (stdP *StdPop) SetArgs(exprs Exprs) error { return setFuncArgs(stdP, exprs, "STDDEV_POP") } +func (stdS *StdSamp) SetArgs(exprs Exprs) error { return setFuncArgs(stdS, exprs, "STDDEV_SAMP") } +func (varP *VarPop) SetArgs(exprs Exprs) error { return setFuncArgs(varP, exprs, "VAR_POP") } +func (varS *VarSamp) SetArgs(exprs Exprs) error { return setFuncArgs(varS, exprs, "VAR_SAMP") } +func (variance *Variance) SetArgs(exprs Exprs) error { return setFuncArgs(variance, exprs, "VARIANCE") } +func (av *AnyValue) SetArgs(exprs Exprs) error { return setFuncArgs(av, exprs, "ANY_VALUE") } + +func (count *Count) SetArgs(exprs Exprs) error { + count.Args = exprs + return nil +} +func (grpConcat *GroupConcatExpr) SetArgs(exprs Exprs) error { + grpConcat.Exprs = exprs + return nil +} + func (sum *Sum) IsDistinct() bool { return sum.Distinct } func (min *Min) IsDistinct() bool { return min.Distinct } func (max *Max) IsDistinct() bool { return max.Distinct } diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index df419e5d7a1..f4f1e3a5455 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -2184,6 +2184,15 @@ func ContainsAggregation(e SQLNode) bool { return hasAggregates } +// setFuncArgs sets the arguments for the aggregation function, while checking that there is only one argument +func setFuncArgs(aggr AggrFunc, exprs Exprs, name string) error { + if len(exprs) != 1 { + return vterrors.VT03001(name) + } + aggr.SetArg(exprs[0]) + return nil +} + // GetFirstSelect gets the first select statement func GetFirstSelect(selStmt SelectStatement) *Select { if selStmt == nil { diff --git a/go/vt/vtgate/planbuilder/fuzz.go b/go/vt/vtgate/planbuilder/fuzz.go index 6b8b37ba43f..79dcca01a53 100644 --- a/go/vt/vtgate/planbuilder/fuzz.go +++ b/go/vt/vtgate/planbuilder/fuzz.go @@ -20,12 +20,12 @@ import ( "sync" "testing" + fuzz "github.com/AdaLogics/go-fuzz-headers" + "vitess.io/vitess/go/json2" "vitess.io/vitess/go/sqltypes" vschemapb "vitess.io/vitess/go/vt/proto/vschema" "vitess.io/vitess/go/vt/vtgate/vindexes" - - fuzz "github.com/AdaLogics/go-fuzz-headers" ) var initter sync.Once diff --git a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go index 67dd0c1d306..715e27ae9c7 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go +++ b/go/vt/vtgate/planbuilder/operators/aggregation_pushing.go @@ -89,20 +89,21 @@ func reachedPhase(ctx *plancontext.PlanningContext, p Phase) bool { // Any columns that are needed to evaluate the subquery needs to be added as // grouping columns to the aggregation being pushed down, and then after the // subquery evaluation we are free to reassemble the total aggregation values. -// This is very similar to how we push aggregation through an shouldRun-join. +// This is very similar to how we push aggregation through an apply-join. func pushAggregationThroughSubquery( ctx *plancontext.PlanningContext, rootAggr *Aggregator, src *SubQueryContainer, ) (Operator, *ApplyResult) { - pushedAggr := rootAggr.SplitAggregatorBelowOperators([]Operator{src.Outer}) + pushedAggr := rootAggr.SplitAggregatorBelowOperators(ctx, []Operator{src.Outer}) for _, subQuery := range src.Inner { lhsCols := subQuery.OuterExpressionsNeeded(ctx, src.Outer) for _, colName := range lhsCols { - idx := slices.IndexFunc(pushedAggr.Columns, func(ae *sqlparser.AliasedExpr) bool { + findColName := func(ae *sqlparser.AliasedExpr) bool { return ctx.SemTable.EqualsExpr(ae.Expr, colName) - }) - if idx >= 0 { + } + if slices.IndexFunc(pushedAggr.Columns, findColName) >= 0 { + // we already have the column, no need to push it again continue } pushedAggr.addColumnWithoutPushing(ctx, aeWrap(colName), true) @@ -111,8 +112,10 @@ func pushAggregationThroughSubquery( src.Outer = pushedAggr - for _, aggregation := range pushedAggr.Aggregations { - aggregation.Original.Expr = rewriteColNameToArgument(ctx, aggregation.Original.Expr, aggregation.SubQueryExpression, src.Inner...) + for _, aggr := range pushedAggr.Aggregations { + // we rewrite columns in the aggregation to use the argument form of the subquery + aggr.Original.Expr = rewriteColNameToArgument(ctx, aggr.Original.Expr, aggr.SubQueryExpression, src.Inner...) + pushedAggr.Columns[aggr.ColOffset].Expr = rewriteColNameToArgument(ctx, pushedAggr.Columns[aggr.ColOffset].Expr, aggr.SubQueryExpression, src.Inner...) } if !rootAggr.Original { @@ -147,7 +150,7 @@ func pushAggregationThroughRoute( route *Route, ) (Operator, *ApplyResult) { // Create a new aggregator to be placed below the route. - aggrBelowRoute := aggregator.SplitAggregatorBelowOperators(route.Inputs()) + aggrBelowRoute := aggregator.SplitAggregatorBelowOperators(ctx, route.Inputs()) aggrBelowRoute.Aggregations = nil pushAggregations(ctx, aggregator, aggrBelowRoute) @@ -248,7 +251,7 @@ func pushAggregationThroughFilter( ) (Operator, *ApplyResult) { columnsNeeded := collectColNamesNeeded(ctx, filter) - pushedAggr := aggregator.SplitAggregatorBelowOperators([]Operator{filter.Source}) + pushedAggr := aggregator.SplitAggregatorBelowOperators(ctx, []Operator{filter.Source}) withNextColumn: for _, col := range columnsNeeded { for _, gb := range pushedAggr.Grouping { diff --git a/go/vt/vtgate/planbuilder/operators/aggregator.go b/go/vt/vtgate/planbuilder/operators/aggregator.go index 49081eb6a10..e9fee905024 100644 --- a/go/vt/vtgate/planbuilder/operators/aggregator.go +++ b/go/vt/vtgate/planbuilder/operators/aggregator.go @@ -379,6 +379,21 @@ func (a *Aggregator) planOffsets(ctx *plancontext.PlanningContext) Operator { return nil } +func (aggr Aggr) setPushColumn(exprs sqlparser.Exprs) { + if aggr.Func == nil { + if len(exprs) > 1 { + panic(vterrors.VT13001(fmt.Sprintf("unexpected number of expression in an random aggregation: %s", sqlparser.String(exprs)))) + } + aggr.Original.Expr = exprs[0] + return + } + + err := aggr.Func.SetArgs(exprs) + if err != nil { + panic(err) + } +} + func (aggr Aggr) getPushColumn() sqlparser.Expr { switch aggr.OpCode { case opcode.AggregateAnyValue: @@ -398,6 +413,17 @@ func (aggr Aggr) getPushColumn() sqlparser.Expr { } } +func (aggr Aggr) getPushColumnExprs() sqlparser.Exprs { + switch aggr.OpCode { + case opcode.AggregateAnyValue: + return sqlparser.Exprs{aggr.Original.Expr} + case opcode.AggregateCountStar: + return sqlparser.Exprs{sqlparser.NewIntLiteral("1")} + default: + return aggr.Func.GetArgs() + } +} + func (a *Aggregator) planOffsetsNotPushed(ctx *plancontext.PlanningContext) { a.Source = newAliasedProjection(a.Source) // we need to keep things in the column order, so we can't iterate over the aggregations or groupings @@ -498,11 +524,23 @@ func (a *Aggregator) internalAddColumn(ctx *plancontext.PlanningContext, aliased // SplitAggregatorBelowOperators returns the aggregator that will live under the Route. // This is used when we are splitting the aggregation so one part is done // at the mysql level and one part at the vtgate level -func (a *Aggregator) SplitAggregatorBelowOperators(input []Operator) *Aggregator { +func (a *Aggregator) SplitAggregatorBelowOperators(ctx *plancontext.PlanningContext, input []Operator) *Aggregator { newOp := a.Clone(input).(*Aggregator) newOp.Pushed = false newOp.Original = false newOp.DT = nil + + // We need to make sure that the columns are cloned so that the original operator is not affected + // by the changes we make to the new operator + newOp.Columns = slice.Map(a.Columns, func(from *sqlparser.AliasedExpr) *sqlparser.AliasedExpr { + return ctx.SemTable.Clone(from).(*sqlparser.AliasedExpr) + }) + for idx, aggr := range newOp.Aggregations { + newOp.Aggregations[idx].Original = ctx.SemTable.Clone(aggr.Original).(*sqlparser.AliasedExpr) + } + for idx, gb := range newOp.Grouping { + newOp.Grouping[idx].Inner = ctx.SemTable.Clone(gb.Inner).(sqlparser.Expr) + } return newOp } diff --git a/go/vt/vtgate/planbuilder/operators/helpers.go b/go/vt/vtgate/planbuilder/operators/helpers.go index 0049a919e2a..31d9bcfd279 100644 --- a/go/vt/vtgate/planbuilder/operators/helpers.go +++ b/go/vt/vtgate/planbuilder/operators/helpers.go @@ -26,13 +26,13 @@ import ( "vitess.io/vitess/go/vt/vtgate/vindexes" ) +type compactable interface { + // Compact implement this interface for operators that have easy to see optimisations + Compact(ctx *plancontext.PlanningContext) (Operator, *ApplyResult) +} + // compact will optimise the operator tree into a smaller but equivalent version func compact(ctx *plancontext.PlanningContext, op Operator) Operator { - type compactable interface { - // Compact implement this interface for operators that have easy to see optimisations - Compact(ctx *plancontext.PlanningContext) (Operator, *ApplyResult) - } - newOp := BottomUp(op, TableID, func(op Operator, _ semantics.TableSet, _ bool) (Operator, *ApplyResult) { newOp, ok := op.(compactable) if !ok { diff --git a/go/vt/vtgate/planbuilder/operators/horizon_expanding.go b/go/vt/vtgate/planbuilder/operators/horizon_expanding.go index fc980038f7f..3f7700eed9d 100644 --- a/go/vt/vtgate/planbuilder/operators/horizon_expanding.go +++ b/go/vt/vtgate/planbuilder/operators/horizon_expanding.go @@ -24,6 +24,7 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" + "vitess.io/vitess/go/vt/vtgate/semantics" ) func expandHorizon(ctx *plancontext.PlanningContext, horizon *Horizon) (Operator, *ApplyResult) { @@ -115,17 +116,27 @@ func expandSelectHorizon(ctx *plancontext.PlanningContext, horizon *Horizon, sel } func expandOrderBy(ctx *plancontext.PlanningContext, op Operator, qp *QueryProjection) Operator { - proj := newAliasedProjection(op) var newOrder []OrderBy sqc := &SubQueryBuilder{} + proj, ok := op.(*Projection) + for _, expr := range qp.OrderExprs { + // Attempt to extract any subqueries within the expression newExpr, subqs := sqc.pullOutValueSubqueries(ctx, expr.SimplifiedExpr, TableID(op), false) if newExpr == nil { - // no subqueries found, let's move on + // If no subqueries are found, retain the original order expression newOrder = append(newOrder, expr) continue } - proj.addSubqueryExpr(aeWrap(newExpr), newExpr, subqs...) + + // If the operator is not a projection, we cannot handle subqueries with aggregation + if !ok { + panic(vterrors.VT12001("subquery with aggregation in order by")) + } + + // Add the new subquery expression to the projection + proj.addSubqueryExpr(ctx, aeWrap(newExpr), newExpr, subqs...) + // Replace the original order expression with the new expression containing subqueries newOrder = append(newOrder, OrderBy{ Inner: &sqlparser.Order{ Expr: newExpr, @@ -133,15 +144,14 @@ func expandOrderBy(ctx *plancontext.PlanningContext, op Operator, qp *QueryProje }, SimplifiedExpr: newExpr, }) - } - if len(proj.Columns.GetColumns()) > 0 { - // if we had to project columns for the ordering, - // we need the projection as source - op = proj + // Update the source of the projection if we have it + if proj != nil { + proj.Source = sqc.getRootOperator(proj.Source, nil) } + // Return the updated operator with the new order by expressions return &Ordering{ Source: op, Order: newOrder, @@ -153,6 +163,7 @@ func createProjectionFromSelect(ctx *plancontext.PlanningContext, horizon *Horiz var dt *DerivedTable if horizon.TableId != nil { + // if we are dealing with a derived table, we need to create a derived table object dt = &DerivedTable{ TableID: *horizon.TableId, Alias: horizon.Alias, @@ -160,13 +171,13 @@ func createProjectionFromSelect(ctx *plancontext.PlanningContext, horizon *Horiz } } - if !qp.NeedsAggregation() { - projX := createProjectionWithoutAggr(ctx, qp, horizon.src()) - projX.DT = dt - return projX + if qp.NeedsAggregation() { + return createProjectionWithAggr(ctx, qp, dt, horizon.src()) } - return createProjectionWithAggr(ctx, qp, dt, horizon.src()) + projX := createProjectionWithoutAggr(ctx, qp, horizon.src()) + projX.DT = dt + return projX } func createProjectionWithAggr(ctx *plancontext.PlanningContext, qp *QueryProjection, dt *DerivedTable, src Operator) Operator { @@ -183,13 +194,8 @@ func createProjectionWithAggr(ctx *plancontext.PlanningContext, qp *QueryProject // Go through all aggregations and check for any subquery. sqc := &SubQueryBuilder{} - outerID := TableID(src) for idx, aggr := range aggregations { - expr := aggr.Original.Expr - newExpr, subqs := sqc.pullOutValueSubqueries(ctx, expr, outerID, false) - if newExpr != nil { - aggregations[idx].SubQueryExpression = subqs - } + aggregations[idx] = pullOutValueSubqueries(ctx, aggr, sqc, TableID(src)) } aggrOp.Source = sqc.getRootOperator(src, nil) @@ -200,6 +206,25 @@ func createProjectionWithAggr(ctx *plancontext.PlanningContext, qp *QueryProject return createProjectionForSimpleAggregation(ctx, aggrOp, qp) } +func pullOutValueSubqueries(ctx *plancontext.PlanningContext, aggr Aggr, sqc *SubQueryBuilder, outerID semantics.TableSet) Aggr { + exprs := aggr.getPushColumnExprs() + var newExprs sqlparser.Exprs + for _, expr := range exprs { + newExpr, subqs := sqc.pullOutValueSubqueries(ctx, expr, outerID, false) + if newExpr != nil { + newExprs = append(newExprs, newExpr) + aggr.SubQueryExpression = append(aggr.SubQueryExpression, subqs...) + } else { + newExprs = append(newExprs, expr) + } + } + if len(aggr.SubQueryExpression) > 0 { + aggr.setPushColumn(newExprs) + } + + return aggr +} + func createProjectionForSimpleAggregation(ctx *plancontext.PlanningContext, a *Aggregator, qp *QueryProjection) Operator { outer: for colIdx, expr := range qp.SelectExprs { @@ -285,7 +310,7 @@ func createProjectionWithoutAggr(ctx *plancontext.PlanningContext, qp *QueryProj // there was no subquery in this expression proj.addUnexploredExpr(org, expr) } else { - proj.addSubqueryExpr(org, newExpr, subqs...) + proj.addSubqueryExpr(ctx, org, newExpr, subqs...) } } proj.Source = sqc.getRootOperator(src, nil) diff --git a/go/vt/vtgate/planbuilder/operators/projection.go b/go/vt/vtgate/planbuilder/operators/projection.go index 869cacc005a..6326fcd2ac7 100644 --- a/go/vt/vtgate/planbuilder/operators/projection.go +++ b/go/vt/vtgate/planbuilder/operators/projection.go @@ -229,11 +229,14 @@ func (p *Projection) canPush(ctx *plancontext.PlanningContext) bool { } func (p *Projection) GetAliasedProjections() (AliasedProjections, error) { - ap, ok := p.Columns.(AliasedProjections) - if !ok { + switch cols := p.Columns.(type) { + case AliasedProjections: + return cols, nil + case nil: + return nil, nil + default: return nil, vterrors.VT09015() } - return ap, nil } func (p *Projection) isDerived() bool { @@ -274,8 +277,7 @@ func (p *Projection) addProjExpr(pe ...*ProjExpr) int { } offset := len(ap) - ap = append(ap, pe...) - p.Columns = ap + p.Columns = append(ap, pe...) return offset } @@ -284,7 +286,18 @@ func (p *Projection) addUnexploredExpr(ae *sqlparser.AliasedExpr, e sqlparser.Ex return p.addProjExpr(newProjExprWithInner(ae, e)) } -func (p *Projection) addSubqueryExpr(ae *sqlparser.AliasedExpr, expr sqlparser.Expr, sqs ...*SubQuery) { +func (p *Projection) addSubqueryExpr(ctx *plancontext.PlanningContext, ae *sqlparser.AliasedExpr, expr sqlparser.Expr, sqs ...*SubQuery) { + ap, err := p.GetAliasedProjections() + if err != nil { + panic(err) + } + for _, projExpr := range ap { + if ctx.SemTable.EqualsExprWithDeps(projExpr.EvalExpr, expr) { + // if we already have this column, we can just return the offset + return + } + } + pe := newProjExprWithInner(ae, expr) pe.Info = SubQueryExpression(sqs) diff --git a/go/vt/vtgate/planbuilder/operators/query_planning.go b/go/vt/vtgate/planbuilder/operators/query_planning.go index b20cad7c125..9a48599b2b0 100644 --- a/go/vt/vtgate/planbuilder/operators/query_planning.go +++ b/go/vt/vtgate/planbuilder/operators/query_planning.go @@ -20,12 +20,10 @@ import ( "fmt" "io" - "vitess.io/vitess/go/vt/vtgate/engine" - + "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/evalengine" - - "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -355,23 +353,14 @@ func tryPushOrdering(ctx *plancontext.PlanningContext, in *Ordering) (Operator, return Swap(in, src, "push ordering under filter") case *ApplyJoin: if canPushLeft(ctx, src, in.Order) { - // ApplyJoin is stable in regard to the columns coming from the LHS, - // so if all the ordering columns come from the LHS, we can push down the Ordering there - src.LHS, in.Source = in, src.LHS - return src, Rewrote("push down ordering on the LHS of a join") + return pushOrderLeftOfJoin(src, in) } case *Ordering: // we'll just remove the order underneath. The top order replaces whatever was incoming in.Source = src.Source return in, Rewrote("remove double ordering") case *Projection: - // we can move ordering under a projection if it's not introducing a column we're sorting by - for _, by := range in.Order { - if !mustFetchFromInput(ctx, by.SimplifiedExpr) { - return in, NoRewrite - } - } - return Swap(in, src, "push ordering under projection") + return pushOrderingUnderProjection(ctx, in, src) case *Aggregator: if !src.QP.AlignGroupByAndOrderBy(ctx) && !overlaps(ctx, in.Order, src.Grouping) { return in, NoRewrite @@ -379,29 +368,65 @@ func tryPushOrdering(ctx *plancontext.PlanningContext, in *Ordering) (Operator, return pushOrderingUnderAggr(ctx, in, src) case *SubQueryContainer: - outerTableID := TableID(src.Outer) - for _, order := range in.Order { - deps := ctx.SemTable.RecursiveDeps(order.Inner.Expr) - if !deps.IsSolvedBy(outerTableID) { - return in, NoRewrite - } - } - src.Outer, in.Source = in, src.Outer - return src, Rewrote("push ordering into outer side of subquery") + return pushOrderingToOuterOfSubqueryContainer(ctx, in, src) case *SubQuery: - outerTableID := TableID(src.Outer) - for _, order := range in.Order { - deps := ctx.SemTable.RecursiveDeps(order.Inner.Expr) - if !deps.IsSolvedBy(outerTableID) { - return in, NoRewrite - } - } - src.Outer, in.Source = in, src.Outer - return src, Rewrote("push ordering into outer side of subquery") + return pushOrderingToOuterOfSubquery(ctx, in, src) } return in, NoRewrite } +func pushOrderingToOuterOfSubquery(ctx *plancontext.PlanningContext, in *Ordering, sq *SubQuery) (Operator, *ApplyResult) { + outerTableID := TableID(sq.Outer) + for idx, order := range in.Order { + deps := ctx.SemTable.RecursiveDeps(order.Inner.Expr) + if !deps.IsSolvedBy(outerTableID) { + return in, NoRewrite + } + in.Order[idx].SimplifiedExpr = sq.rewriteColNameToArgument(order.SimplifiedExpr) + in.Order[idx].Inner.Expr = sq.rewriteColNameToArgument(order.Inner.Expr) + } + sq.Outer, in.Source = in, sq.Outer + return sq, Rewrote("push ordering into outer side of subquery") +} + +func pushOrderingToOuterOfSubqueryContainer(ctx *plancontext.PlanningContext, in *Ordering, subq *SubQueryContainer) (Operator, *ApplyResult) { + outerTableID := TableID(subq.Outer) + for _, order := range in.Order { + deps := ctx.SemTable.RecursiveDeps(order.Inner.Expr) + if !deps.IsSolvedBy(outerTableID) { + return in, NoRewrite + } + } + subq.Outer, in.Source = in, subq.Outer + return subq, Rewrote("push ordering into outer side of subquery") +} + +func pushOrderingUnderProjection(ctx *plancontext.PlanningContext, in *Ordering, proj *Projection) (Operator, *ApplyResult) { + // we can move ordering under a projection if it's not introducing a column we're sorting by + for _, by := range in.Order { + if !mustFetchFromInput(ctx, by.SimplifiedExpr) { + return in, NoRewrite + } + } + ap, ok := proj.Columns.(AliasedProjections) + if !ok { + return in, NoRewrite + } + for _, projExpr := range ap { + if projExpr.Info != nil { + return in, NoRewrite + } + } + return Swap(in, proj, "push ordering under projection") +} + +func pushOrderLeftOfJoin(src *ApplyJoin, in *Ordering) (Operator, *ApplyResult) { + // ApplyJoin is stable in regard to the columns coming from the LHS, + // so if all the ordering columns come from the LHS, we can push down the Ordering there + src.LHS, in.Source = in, src.LHS + return src, Rewrote("push down ordering on the LHS of a join") +} + func overlaps(ctx *plancontext.PlanningContext, order []OrderBy, grouping []GroupBy) bool { ordering: for _, orderBy := range order { @@ -672,6 +697,11 @@ func addTruncationOrProjectionToReturnOutput(ctx *plancontext.PlanningContext, s } func colNamesAlign(expected, actual sqlparser.SelectExprs) bool { + if len(expected) > len(actual) { + // if we expect more columns than we have, we can't align + return false + } + for i, seE := range expected { switch se := seE.(type) { case *sqlparser.AliasedExpr: @@ -681,7 +711,7 @@ func colNamesAlign(expected, actual sqlparser.SelectExprs) bool { case *sqlparser.StarExpr: actualStar, isStar := actual[i].(*sqlparser.StarExpr) if !isStar { - panic("I DONT THINK THIS CAN HAPPEN") + panic(vterrors.VT13001(fmt.Sprintf("star expression is expected here, found: %T", actual[i]))) } if !sqlparser.Equals.RefOfStarExpr(se, actualStar) { return false diff --git a/go/vt/vtgate/planbuilder/operators/queryprojection.go b/go/vt/vtgate/planbuilder/operators/queryprojection.go index cbacdd25e90..56e0fe8d623 100644 --- a/go/vt/vtgate/planbuilder/operators/queryprojection.go +++ b/go/vt/vtgate/planbuilder/operators/queryprojection.go @@ -69,7 +69,7 @@ type ( // Aggr encodes all information needed for aggregation functions Aggr struct { Original *sqlparser.AliasedExpr - Func sqlparser.AggrFunc + Func sqlparser.AggrFunc // if we are missing a Func, it means this is a AggregateAnyValue OpCode opcode.AggregateOpcode // OriginalOpCode will contain opcode.AggregateUnassigned unless we are changing opcode while pushing them down @@ -269,8 +269,7 @@ func (qp *QueryProjection) addOrderBy(ctx *plancontext.PlanningContext, orderBy canPushSorting := true es := &expressionSet{} for _, order := range orderBy { - if sqlparser.IsNull(order.Expr) { - // ORDER BY null can safely be ignored + if canIgnoreOrdering(ctx, order.Expr) { continue } if !es.add(ctx, order.Expr) { @@ -284,6 +283,18 @@ func (qp *QueryProjection) addOrderBy(ctx *plancontext.PlanningContext, orderBy } } +// canIgnoreOrdering returns true if the ordering expression has no effect on the result. +func canIgnoreOrdering(ctx *plancontext.PlanningContext, expr sqlparser.Expr) bool { + switch expr.(type) { + case *sqlparser.NullVal, *sqlparser.Literal, *sqlparser.Argument: + return true + case *sqlparser.Subquery: + return ctx.SemTable.RecursiveDeps(expr).IsEmpty() + default: + return false + } +} + func (qp *QueryProjection) calculateDistinct(ctx *plancontext.PlanningContext) { if qp.Distinct && !qp.HasAggr { distinct := qp.useGroupingOverDistinct(ctx) diff --git a/go/vt/vtgate/planbuilder/operators/subquery.go b/go/vt/vtgate/planbuilder/operators/subquery.go index e2f046f4a4d..0e9cdb92d84 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery.go +++ b/go/vt/vtgate/planbuilder/operators/subquery.go @@ -53,7 +53,8 @@ type SubQuery struct { // We use this information to fail the planning if we are unable to merge the subquery with a route. correlated bool - IsProjection bool + // IsArgument is set to true if the subquery puts the + IsArgument bool } func (sq *SubQuery) planOffsets(ctx *plancontext.PlanningContext) Operator { @@ -156,8 +157,8 @@ func (sq *SubQuery) SetInputs(inputs []Operator) { func (sq *SubQuery) ShortDescription() string { var typ string - if sq.IsProjection { - typ = "PROJ" + if sq.IsArgument { + typ = "ARGUMENT" } else { typ = "FILTER" } @@ -175,8 +176,11 @@ func (sq *SubQuery) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparse return sq } -func (sq *SubQuery) AddColumn(ctx *plancontext.PlanningContext, reuseExisting bool, addToGroupBy bool, exprs *sqlparser.AliasedExpr) int { - return sq.Outer.AddColumn(ctx, reuseExisting, addToGroupBy, exprs) +func (sq *SubQuery) AddColumn(ctx *plancontext.PlanningContext, reuseExisting bool, addToGroupBy bool, ae *sqlparser.AliasedExpr) int { + ae = sqlparser.Clone(ae) + // we need to rewrite the column name to an argument if it's the same as the subquery column name + ae.Expr = rewriteColNameToArgument(ctx, ae.Expr, []*SubQuery{sq}, sq) + return sq.Outer.AddColumn(ctx, reuseExisting, addToGroupBy, ae) } func (sq *SubQuery) AddWSColumn(ctx *plancontext.PlanningContext, offset int, underRoute bool) int { @@ -210,7 +214,7 @@ func (sq *SubQuery) settle(ctx *plancontext.PlanningContext, outer Operator) Ope if sq.correlated && sq.FilterType != opcode.PulloutExists { panic(correlatedSubqueryErr) } - if sq.IsProjection { + if sq.IsArgument { if len(sq.GetMergePredicates()) > 0 { // this means that we have a correlated subquery on our hands panic(correlatedSubqueryErr) @@ -293,3 +297,18 @@ func (sq *SubQuery) mapExpr(f func(expr sqlparser.Expr) sqlparser.Expr) { sq.Original = f(sq.Original) sq.originalSubquery = f(sq.originalSubquery).(*sqlparser.Subquery) } + +func (sq *SubQuery) rewriteColNameToArgument(expr sqlparser.Expr) sqlparser.Expr { + pre := func(cursor *sqlparser.Cursor) bool { + colName, ok := cursor.Node().(*sqlparser.ColName) + if !ok || colName.Qualifier.NonEmpty() || !colName.Name.EqualString(sq.ArgName) { + // we only want to rewrite the column name to an argument if it's the right column + return true + } + + cursor.Replace(sqlparser.NewArgument(sq.ArgName)) + return true + } + + return sqlparser.Rewrite(expr, pre, nil).(sqlparser.Expr) +} diff --git a/go/vt/vtgate/planbuilder/operators/subquery_builder.go b/go/vt/vtgate/planbuilder/operators/subquery_builder.go index f2fdefeb007..c2256df06f4 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_builder.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_builder.go @@ -159,7 +159,7 @@ func createSubquery( parent sqlparser.Expr, argName string, filterType opcode.PulloutOpcode, - isProjection bool, + isArg bool, ) *SubQuery { topLevel := ctx.SemTable.EqualsExpr(original, parent) original = cloneASTAndSemState(ctx, original) @@ -181,7 +181,7 @@ func createSubquery( Original: original, ArgName: argName, originalSubquery: originalSq, - IsProjection: isProjection, + IsArgument: isArg, TopLevel: topLevel, JoinColumns: joinCols, correlated: correlated, diff --git a/go/vt/vtgate/planbuilder/operators/subquery_container.go b/go/vt/vtgate/planbuilder/operators/subquery_container.go index edbbec1125e..3f5c3eed254 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_container.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_container.go @@ -43,7 +43,7 @@ func (sqc *SubQueryContainer) Clone(inputs []Operator) Operator { if !ok { panic("got bad input") } - result.Inner = append(result.Inner, inner) + result.addInner(inner) } return result } @@ -94,3 +94,13 @@ func (sqc *SubQueryContainer) GetColumns(ctx *plancontext.PlanningContext) []*sq func (sqc *SubQueryContainer) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.SelectExprs { return sqc.Outer.GetSelectExprs(ctx) } + +func (sqc *SubQueryContainer) addInner(inner *SubQuery) { + for _, sq := range sqc.Inner { + if sq.ArgName == inner.ArgName { + // we already have this subquery + return + } + } + sqc.Inner = append(sqc.Inner, inner) +} diff --git a/go/vt/vtgate/planbuilder/operators/subquery_planning.go b/go/vt/vtgate/planbuilder/operators/subquery_planning.go index 145a0707347..cdc0b8b191a 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_planning.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_planning.go @@ -100,8 +100,11 @@ func settleSubqueries(ctx *plancontext.PlanningContext, op Operator) Operator { newExpr, rewritten := rewriteMergedSubqueryExpr(ctx, aggr.SubQueryExpression, aggr.Original.Expr) if rewritten { aggr.Original.Expr = newExpr + op.Columns[aggr.ColOffset].Expr = newExpr } } + case *Ordering: + op.settleOrderingExpressions(ctx) } return op, NoRewrite } @@ -109,6 +112,29 @@ func settleSubqueries(ctx *plancontext.PlanningContext, op Operator) Operator { return BottomUp(op, TableID, visit, nil) } +func (o *Ordering) settleOrderingExpressions(ctx *plancontext.PlanningContext) { + for idx, order := range o.Order { + for _, sq := range ctx.MergedSubqueries { + arg := ctx.GetReservedArgumentFor(sq) + expr := sqlparser.Rewrite(order.SimplifiedExpr, nil, func(cursor *sqlparser.Cursor) bool { + switch expr := cursor.Node().(type) { + case *sqlparser.ColName: + if expr.Name.String() == arg { + cursor.Replace(sq) + } + case *sqlparser.Argument: + if expr.Name == arg { + cursor.Replace(sq) + } + } + + return true + }) + o.Order[idx].SimplifiedExpr = expr.(sqlparser.Expr) + } + } +} + func mergeSubqueryExpr(ctx *plancontext.PlanningContext, pe *ProjExpr) { se, ok := pe.Info.(SubQueryExpression) if !ok { @@ -319,7 +345,7 @@ func addSubQuery(in Operator, inner *SubQuery) Operator { } } - sql.Inner = append(sql.Inner, inner) + sql.addInner(inner) return sql } @@ -477,7 +503,7 @@ func tryMergeSubqueryWithOuter(ctx *plancontext.PlanningContext, subQuery *SubQu if op == nil { return outer, NoRewrite } - if !subQuery.IsProjection { + if !subQuery.IsArgument { op.Source = newFilter(outer.Source, subQuery.Original) } ctx.MergedSubqueries = append(ctx.MergedSubqueries, subQuery.originalSubquery) @@ -582,7 +608,7 @@ func (s *subqueryRouteMerger) merge(ctx *plancontext.PlanningContext, inner, out var src Operator if isSharded { src = s.outer.Source - if !s.subq.IsProjection { + if !s.subq.IsArgument { src = newFilter(s.outer.Source, s.original) } } else { @@ -643,7 +669,7 @@ func (s *subqueryRouteMerger) rewriteASTExpression(ctx *plancontext.PlanningCont panic(err) } - if s.subq.IsProjection { + if s.subq.IsArgument { ctx.SemTable.CopySemanticInfo(s.subq.originalSubquery.Select, subqStmt) s.subq.originalSubquery.Select = subqStmt } else { diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index 387684149bf..f49994d37b2 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -28,10 +28,9 @@ import ( "strings" "testing" - "github.com/stretchr/testify/suite" - "github.com/nsf/jsondiff" "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/utils" diff --git a/go/vt/vtgate/planbuilder/planner_test.go b/go/vt/vtgate/planbuilder/planner_test.go index 6ad1bb4116c..c3caf9f3536 100644 --- a/go/vt/vtgate/planbuilder/planner_test.go +++ b/go/vt/vtgate/planbuilder/planner_test.go @@ -19,11 +19,10 @@ package planbuilder import ( "testing" - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" "vitess.io/vitess/go/vt/vtgate/vindexes" ) diff --git a/go/vt/vtgate/planbuilder/predicate_rewrite_test.go b/go/vt/vtgate/planbuilder/predicate_rewrite_test.go index f103709d9e3..4945c2bb7ff 100644 --- a/go/vt/vtgate/planbuilder/predicate_rewrite_test.go +++ b/go/vt/vtgate/planbuilder/predicate_rewrite_test.go @@ -27,7 +27,6 @@ import ( "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql/collations" - "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtenv" diff --git a/go/vt/vtgate/planbuilder/rewrite_test.go b/go/vt/vtgate/planbuilder/rewrite_test.go index 7902b69e8f9..398e0b1dd1b 100644 --- a/go/vt/vtgate/planbuilder/rewrite_test.go +++ b/go/vt/vtgate/planbuilder/rewrite_test.go @@ -19,12 +19,11 @@ package planbuilder import ( "testing" - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/semantics" ) diff --git a/go/vt/vtgate/planbuilder/set.go b/go/vt/vtgate/planbuilder/set.go index bf6820b7489..77f20be40f9 100644 --- a/go/vt/vtgate/planbuilder/set.go +++ b/go/vt/vtgate/planbuilder/set.go @@ -21,18 +21,14 @@ import ( "strconv" "strings" - "vitess.io/vitess/go/vt/sysvars" - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - - "vitess.io/vitess/go/vt/vtgate/evalengine" - - "vitess.io/vitess/go/vt/vtgate/vindexes" - - "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/sysvars" + "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" + "vitess.io/vitess/go/vt/vtgate/evalengine" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" + "vitess.io/vitess/go/vt/vtgate/vindexes" ) type ( diff --git a/go/vt/vtgate/planbuilder/show_test.go b/go/vt/vtgate/planbuilder/show_test.go index 931c914149d..bfdb9a623a0 100644 --- a/go/vt/vtgate/planbuilder/show_test.go +++ b/go/vt/vtgate/planbuilder/show_test.go @@ -21,15 +21,13 @@ import ( "fmt" "testing" - "vitess.io/vitess/go/test/vschemawrapper" - "vitess.io/vitess/go/vt/vtenv" - "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql/collations" - "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/vschemawrapper" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/vtgate/vindexes" ) diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json index 2fa0df2a847..f94c75f084b 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json @@ -2272,76 +2272,66 @@ } }, { - "comment": "select (select col from user limit 1) as a from user join user_extra order by a", + "comment": "ORDER BY subquery", "query": "select (select col from user limit 1) as a from user join user_extra order by a", "plan": { "QueryType": "SELECT", "Original": "select (select col from user limit 1) as a from user join user_extra order by a", "Instructions": { - "OperatorType": "SimpleProjection", - "ColumnNames": [ - "0:a" - ], - "Columns": "1", + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "L:0", + "TableName": "`user`_user_extra", "Inputs": [ { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0", - "TableName": "`user`_user_extra", + "OperatorType": "UncorrelatedSubquery", + "Variant": "PulloutValue", + "PulloutVars": [ + "__sq1" + ], "Inputs": [ { - "OperatorType": "UncorrelatedSubquery", - "Variant": "PulloutValue", - "PulloutVars": [ - "__sq1" - ], + "InputName": "SubQuery", + "OperatorType": "Limit", + "Count": "1", "Inputs": [ { - "InputName": "SubQuery", - "OperatorType": "Limit", - "Count": "1", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select col from `user` where 1 != 1", - "Query": "select col from `user` limit 1", - "Table": "`user`" - } - ] - }, - { - "InputName": "Outer", "OperatorType": "Route", "Variant": "Scatter", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select :__sq1 as __sq1, weight_string(:__sq1) from `user` where 1 != 1", - "OrderBy": "(0|1) ASC", - "Query": "select :__sq1 as __sq1, weight_string(:__sq1) from `user` order by __sq1 asc", + "FieldQuery": "select col from `user` where 1 != 1", + "Query": "select col from `user` limit 1", "Table": "`user`" } ] }, { + "InputName": "Outer", "OperatorType": "Route", "Variant": "Scatter", "Keyspace": { "Name": "user", "Sharded": true }, - "FieldQuery": "select 1 from user_extra where 1 != 1", - "Query": "select 1 from user_extra", - "Table": "user_extra" + "FieldQuery": "select :__sq1 as a from `user` where 1 != 1", + "Query": "select :__sq1 as a from `user`", + "Table": "`user`" } ] + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select 1 from user_extra where 1 != 1", + "Query": "select 1 from user_extra", + "Table": "user_extra" } ] }, diff --git a/go/vt/vtgate/planbuilder/vexplain.go b/go/vt/vtgate/planbuilder/vexplain.go index ef75dc15a21..21a35f02967 100644 --- a/go/vt/vtgate/planbuilder/vexplain.go +++ b/go/vt/vtgate/planbuilder/vexplain.go @@ -20,8 +20,6 @@ import ( "context" "encoding/json" - "vitess.io/vitess/go/vt/vtgate/vindexes" - "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/key" querypb "vitess.io/vitess/go/vt/proto/query" @@ -31,6 +29,7 @@ import ( "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" + "vitess.io/vitess/go/vt/vtgate/vindexes" ) func buildVExplainPlan(ctx context.Context, vexplainStmt *sqlparser.VExplainStmt, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*planResult, error) { diff --git a/go/vt/vtgate/planbuilder/vindex_func.go b/go/vt/vtgate/planbuilder/vindex_func.go index 6db9adab051..6b8da55d65a 100644 --- a/go/vt/vtgate/planbuilder/vindex_func.go +++ b/go/vt/vtgate/planbuilder/vindex_func.go @@ -20,10 +20,9 @@ import ( "fmt" "vitess.io/vitess/go/mysql/collations" - "vitess.io/vitess/go/vt/vterrors" - querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" ) diff --git a/go/vt/vtgate/planbuilder/vstream.go b/go/vt/vtgate/planbuilder/vstream.go index fe07a4a021b..19713a6ffa3 100644 --- a/go/vt/vtgate/planbuilder/vstream.go +++ b/go/vt/vtgate/planbuilder/vstream.go @@ -20,13 +20,12 @@ import ( "strconv" "strings" - "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" - "vitess.io/vitess/go/vt/key" topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) const defaultLimit = 100 From 3f2d09689c02205ee58efac5ac2c8f0879812612 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Wed, 12 Jun 2024 21:34:52 +0530 Subject: [PATCH 25/40] Topology Server Locking Refactor (#16005) Signed-off-by: Manan Gupta --- go/test/endtoend/topotest/consul/main_test.go | 83 +++++ go/test/endtoend/topotest/etcd2/main_test.go | 86 +++++ go/test/endtoend/topotest/utils/utils.go | 41 +++ go/test/endtoend/topotest/zk2/main_test.go | 83 +++++ go/vt/schemamanager/tablet_executor.go | 2 +- go/vt/topo/keyspace_lock.go | 58 ++++ go/vt/topo/keyspace_lock_test.go | 84 +++++ go/vt/topo/locks.go | 312 +++--------------- go/vt/topo/locks_test.go | 101 ------ go/vt/topo/routing_rules_lock.go | 34 +- go/vt/topo/routing_rules_lock_test.go | 64 +++- go/vt/topo/shard_lock.go | 98 ++++++ .../{topo_lock_test.go => shard_lock_test.go} | 69 ++-- go/vt/topo/shard_test.go | 19 +- go/vt/topo/topo_lock.go | 169 ---------- go/vt/topotools/routing_rules.go | 9 +- go/vt/topotools/routing_rules_test.go | 4 +- 17 files changed, 711 insertions(+), 605 deletions(-) create mode 100644 go/test/endtoend/topotest/utils/utils.go create mode 100644 go/vt/topo/keyspace_lock.go create mode 100644 go/vt/topo/keyspace_lock_test.go delete mode 100644 go/vt/topo/locks_test.go create mode 100644 go/vt/topo/shard_lock.go rename go/vt/topo/{topo_lock_test.go => shard_lock_test.go} (57%) delete mode 100644 go/vt/topo/topo_lock.go diff --git a/go/test/endtoend/topotest/consul/main_test.go b/go/test/endtoend/topotest/consul/main_test.go index 1c278864ced..0f6fa6ce554 100644 --- a/go/test/endtoend/topotest/consul/main_test.go +++ b/go/test/endtoend/topotest/consul/main_test.go @@ -24,7 +24,9 @@ import ( "testing" "time" + topoutils "vitess.io/vitess/go/test/endtoend/topotest/utils" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/topo" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" @@ -140,6 +142,87 @@ func TestTopoRestart(t *testing.T) { } } +// TestShardLocking tests that shard locking works as intended. +func TestShardLocking(t *testing.T) { + // create topo server connection + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctlProcess.TopoGlobalAddress, clusterInstance.VtctlProcess.TopoGlobalRoot) + require.NoError(t, err) + + // Acquire a shard lock. + ctx, unlock, err := ts.LockShard(context.Background(), KeyspaceName, "0", "TestShardLocking") + require.NoError(t, err) + // Check that we can't reacquire it from the same context. + _, _, err = ts.LockShard(ctx, KeyspaceName, "0", "TestShardLocking") + require.ErrorContains(t, err, "lock for shard customer/0 is already held") + // Also check that TryLockShard is non-blocking and returns an error. + _, _, err = ts.TryLockShard(context.Background(), KeyspaceName, "0", "TestShardLocking") + require.ErrorContains(t, err, "node already exists: lock already exists at path keyspaces/customer/shards/0") + // Check that CheckShardLocked doesn't return an error. + err = topo.CheckShardLocked(ctx, KeyspaceName, "0") + require.NoError(t, err) + + // We'll now try to acquire the lock from a different thread. + secondThreadLockAcquired := false + go func() { + _, unlock, err := ts.LockShard(context.Background(), KeyspaceName, "0", "TestShardLocking") + defer unlock(&err) + require.NoError(t, err) + secondThreadLockAcquired = true + }() + + // Wait for some time and ensure that the second acquiring of lock shard is blocked. + time.Sleep(100 * time.Millisecond) + require.False(t, secondThreadLockAcquired) + + // Unlock the shard. + unlock(&err) + // Check that we no longer have shard lock acquired. + err = topo.CheckShardLocked(ctx, KeyspaceName, "0") + require.ErrorContains(t, err, "shard customer/0 is not locked (no lockInfo in map)") + + // Wait to see that the second thread was able to acquire the shard lock. + topoutils.WaitForBoolValue(t, &secondThreadLockAcquired, true) +} + +// TestKeyspaceLocking tests that keyspace locking works as intended. +func TestKeyspaceLocking(t *testing.T) { + // create topo server connection + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctlProcess.TopoGlobalAddress, clusterInstance.VtctlProcess.TopoGlobalRoot) + require.NoError(t, err) + + // Acquire a keyspace lock. + ctx, unlock, err := ts.LockKeyspace(context.Background(), KeyspaceName, "TestKeyspaceLocking") + require.NoError(t, err) + // Check that we can't reacquire it from the same context. + _, _, err = ts.LockKeyspace(ctx, KeyspaceName, "TestKeyspaceLocking") + require.ErrorContains(t, err, "lock for keyspace customer is already held") + // Check that CheckKeyspaceLocked doesn't return an error. + err = topo.CheckKeyspaceLocked(ctx, KeyspaceName) + require.NoError(t, err) + + // We'll now try to acquire the lock from a different thread. + secondThreadLockAcquired := false + go func() { + _, unlock, err := ts.LockKeyspace(context.Background(), KeyspaceName, "TestKeyspaceLocking") + defer unlock(&err) + require.NoError(t, err) + secondThreadLockAcquired = true + }() + + // Wait for some time and ensure that the second acquiring of lock shard is blocked. + time.Sleep(100 * time.Millisecond) + require.False(t, secondThreadLockAcquired) + + // Unlock the keyspace. + unlock(&err) + // Check that we no longer have keyspace lock acquired. + err = topo.CheckKeyspaceLocked(ctx, KeyspaceName) + require.ErrorContains(t, err, "keyspace customer is not locked (no lockInfo in map)") + + // Wait to see that the second thread was able to acquire the shard lock. + topoutils.WaitForBoolValue(t, &secondThreadLockAcquired, true) +} + func execute(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { t.Helper() qr, err := conn.ExecuteFetch(query, 1000, true) diff --git a/go/test/endtoend/topotest/etcd2/main_test.go b/go/test/endtoend/topotest/etcd2/main_test.go index db34bd2ee86..747f2721cdc 100644 --- a/go/test/endtoend/topotest/etcd2/main_test.go +++ b/go/test/endtoend/topotest/etcd2/main_test.go @@ -23,7 +23,9 @@ import ( "testing" "time" + topoutils "vitess.io/vitess/go/test/endtoend/topotest/utils" "vitess.io/vitess/go/test/endtoend/utils" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/log" @@ -111,10 +113,94 @@ func TestTopoDownServingQuery(t *testing.T) { execMulti(t, conn, `insert into t1(c1, c2, c3, c4) values (300,100,300,'abc'); ;; insert into t1(c1, c2, c3, c4) values (301,101,301,'abcd');;`) utils.AssertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)] [INT64(301) INT64(101) INT64(301)]]`) clusterInstance.TopoProcess.TearDown(clusterInstance.Cell, clusterInstance.OriginalVTDATAROOT, clusterInstance.CurrentVTDATAROOT, true, *clusterInstance.TopoFlavorString()) + defer func() { + _ = clusterInstance.TopoProcess.SetupEtcd() + }() time.Sleep(3 * time.Second) utils.AssertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)] [INT64(301) INT64(101) INT64(301)]]`) } +// TestShardLocking tests that shard locking works as intended. +func TestShardLocking(t *testing.T) { + // create topo server connection + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctlProcess.TopoGlobalAddress, clusterInstance.VtctlProcess.TopoGlobalRoot) + require.NoError(t, err) + + // Acquire a shard lock. + ctx, unlock, err := ts.LockShard(context.Background(), KeyspaceName, "0", "TestShardLocking") + require.NoError(t, err) + // Check that we can't reacquire it from the same context. + _, _, err = ts.LockShard(ctx, KeyspaceName, "0", "TestShardLocking") + require.ErrorContains(t, err, "lock for shard customer/0 is already held") + // Also check that TryLockShard is non-blocking and returns an error. + _, _, err = ts.TryLockShard(context.Background(), KeyspaceName, "0", "TestShardLocking") + require.ErrorContains(t, err, "node already exists: lock already exists at path keyspaces/customer/shards/0") + // Check that CheckShardLocked doesn't return an error. + err = topo.CheckShardLocked(ctx, KeyspaceName, "0") + require.NoError(t, err) + + // We'll now try to acquire the lock from a different thread. + secondThreadLockAcquired := false + go func() { + _, unlock, err := ts.LockShard(context.Background(), KeyspaceName, "0", "TestShardLocking") + defer unlock(&err) + require.NoError(t, err) + secondThreadLockAcquired = true + }() + + // Wait for some time and ensure that the second acquiring of lock shard is blocked. + time.Sleep(100 * time.Millisecond) + require.False(t, secondThreadLockAcquired) + + // Unlock the shard. + unlock(&err) + // Check that we no longer have shard lock acquired. + err = topo.CheckShardLocked(ctx, KeyspaceName, "0") + require.ErrorContains(t, err, "shard customer/0 is not locked (no lockInfo in map)") + + // Wait to see that the second thread was able to acquire the shard lock. + topoutils.WaitForBoolValue(t, &secondThreadLockAcquired, true) +} + +// TestKeyspaceLocking tests that keyspace locking works as intended. +func TestKeyspaceLocking(t *testing.T) { + // create topo server connection + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctlProcess.TopoGlobalAddress, clusterInstance.VtctlProcess.TopoGlobalRoot) + require.NoError(t, err) + + // Acquire a keyspace lock. + ctx, unlock, err := ts.LockKeyspace(context.Background(), KeyspaceName, "TestKeyspaceLocking") + require.NoError(t, err) + // Check that we can't reacquire it from the same context. + _, _, err = ts.LockKeyspace(ctx, KeyspaceName, "TestKeyspaceLocking") + require.ErrorContains(t, err, "lock for keyspace customer is already held") + // Check that CheckKeyspaceLocked doesn't return an error. + err = topo.CheckKeyspaceLocked(ctx, KeyspaceName) + require.NoError(t, err) + + // We'll now try to acquire the lock from a different thread. + secondThreadLockAcquired := false + go func() { + _, unlock, err := ts.LockKeyspace(context.Background(), KeyspaceName, "TestKeyspaceLocking") + defer unlock(&err) + require.NoError(t, err) + secondThreadLockAcquired = true + }() + + // Wait for some time and ensure that the second acquiring of lock shard is blocked. + time.Sleep(100 * time.Millisecond) + require.False(t, secondThreadLockAcquired) + + // Unlock the keyspace. + unlock(&err) + // Check that we no longer have keyspace lock acquired. + err = topo.CheckKeyspaceLocked(ctx, KeyspaceName) + require.ErrorContains(t, err, "keyspace customer is not locked (no lockInfo in map)") + + // Wait to see that the second thread was able to acquire the shard lock. + topoutils.WaitForBoolValue(t, &secondThreadLockAcquired, true) +} + func execMulti(t *testing.T, conn *mysql.Conn, query string) []*sqltypes.Result { t.Helper() var res []*sqltypes.Result diff --git a/go/test/endtoend/topotest/utils/utils.go b/go/test/endtoend/topotest/utils/utils.go new file mode 100644 index 00000000000..6b8433b6a7f --- /dev/null +++ b/go/test/endtoend/topotest/utils/utils.go @@ -0,0 +1,41 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package utils + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +// WaitForBoolValue takes a pointer to a boolean and waits for it to reach a certain value. +func WaitForBoolValue(t *testing.T, val *bool, waitFor bool) { + timeout := time.After(15 * time.Second) + for { + select { + case <-timeout: + require.Failf(t, "Failed waiting for bool value", "Timed out waiting for the boolean to become %v", waitFor) + return + default: + if *val == waitFor { + return + } + time.Sleep(100 * time.Millisecond) + } + } +} diff --git a/go/test/endtoend/topotest/zk2/main_test.go b/go/test/endtoend/topotest/zk2/main_test.go index 816bbc72d72..48636331747 100644 --- a/go/test/endtoend/topotest/zk2/main_test.go +++ b/go/test/endtoend/topotest/zk2/main_test.go @@ -23,7 +23,9 @@ import ( "testing" "time" + topoutils "vitess.io/vitess/go/test/endtoend/topotest/utils" "vitess.io/vitess/go/test/endtoend/utils" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/log" @@ -116,6 +118,87 @@ func TestTopoDownServingQuery(t *testing.T) { utils.AssertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)] [INT64(301) INT64(101) INT64(301)]]`) } +// TestShardLocking tests that shard locking works as intended. +func TestShardLocking(t *testing.T) { + // create topo server connection + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctlProcess.TopoGlobalAddress, clusterInstance.VtctlProcess.TopoGlobalRoot) + require.NoError(t, err) + + // Acquire a shard lock. + ctx, unlock, err := ts.LockShard(context.Background(), KeyspaceName, "0", "TestShardLocking") + require.NoError(t, err) + // Check that we can't reacquire it from the same context. + _, _, err = ts.LockShard(ctx, KeyspaceName, "0", "TestShardLocking") + require.ErrorContains(t, err, "lock for shard customer/0 is already held") + // Also check that TryLockShard is non-blocking and returns an error. + _, _, err = ts.TryLockShard(context.Background(), KeyspaceName, "0", "TestShardLocking") + require.ErrorContains(t, err, "node already exists: lock already exists at path keyspaces/customer/shards/0") + // Check that CheckShardLocked doesn't return an error. + err = topo.CheckShardLocked(ctx, KeyspaceName, "0") + require.NoError(t, err) + + // We'll now try to acquire the lock from a different thread. + secondThreadLockAcquired := false + go func() { + _, unlock, err := ts.LockShard(context.Background(), KeyspaceName, "0", "TestShardLocking") + defer unlock(&err) + require.NoError(t, err) + secondThreadLockAcquired = true + }() + + // Wait for some time and ensure that the second acquiring of lock shard is blocked. + time.Sleep(100 * time.Millisecond) + require.False(t, secondThreadLockAcquired) + + // Unlock the shard. + unlock(&err) + // Check that we no longer have shard lock acquired. + err = topo.CheckShardLocked(ctx, KeyspaceName, "0") + require.ErrorContains(t, err, "shard customer/0 is not locked (no lockInfo in map)") + + // Wait to see that the second thread was able to acquire the shard lock. + topoutils.WaitForBoolValue(t, &secondThreadLockAcquired, true) +} + +// TestKeyspaceLocking tests that keyspace locking works as intended. +func TestKeyspaceLocking(t *testing.T) { + // create topo server connection + ts, err := topo.OpenServer(*clusterInstance.TopoFlavorString(), clusterInstance.VtctlProcess.TopoGlobalAddress, clusterInstance.VtctlProcess.TopoGlobalRoot) + require.NoError(t, err) + + // Acquire a keyspace lock. + ctx, unlock, err := ts.LockKeyspace(context.Background(), KeyspaceName, "TestKeyspaceLocking") + require.NoError(t, err) + // Check that we can't reacquire it from the same context. + _, _, err = ts.LockKeyspace(ctx, KeyspaceName, "TestKeyspaceLocking") + require.ErrorContains(t, err, "lock for keyspace customer is already held") + // Check that CheckKeyspaceLocked doesn't return an error. + err = topo.CheckKeyspaceLocked(ctx, KeyspaceName) + require.NoError(t, err) + + // We'll now try to acquire the lock from a different thread. + secondThreadLockAcquired := false + go func() { + _, unlock, err := ts.LockKeyspace(context.Background(), KeyspaceName, "TestKeyspaceLocking") + defer unlock(&err) + require.NoError(t, err) + secondThreadLockAcquired = true + }() + + // Wait for some time and ensure that the second acquiring of lock shard is blocked. + time.Sleep(100 * time.Millisecond) + require.False(t, secondThreadLockAcquired) + + // Unlock the keyspace. + unlock(&err) + // Check that we no longer have keyspace lock acquired. + err = topo.CheckKeyspaceLocked(ctx, KeyspaceName) + require.ErrorContains(t, err, "keyspace customer is not locked (no lockInfo in map)") + + // Wait to see that the second thread was able to acquire the shard lock. + topoutils.WaitForBoolValue(t, &secondThreadLockAcquired, true) +} + func execMulti(t *testing.T, conn *mysql.Conn, query string) []*sqltypes.Result { t.Helper() var res []*sqltypes.Result diff --git a/go/vt/schemamanager/tablet_executor.go b/go/vt/schemamanager/tablet_executor.go index 5397cf9343f..0acae6459db 100644 --- a/go/vt/schemamanager/tablet_executor.go +++ b/go/vt/schemamanager/tablet_executor.go @@ -475,7 +475,7 @@ func (exec *TabletExecutor) Execute(ctx context.Context, sqls []string) *Execute } for index, sql := range sqls { // Attempt to renew lease: - if err := rl.Do(func() error { return topo.CheckKeyspaceLockedAndRenew(ctx, exec.keyspace) }); err != nil { + if err := rl.Do(func() error { return topo.CheckKeyspaceLocked(ctx, exec.keyspace) }); err != nil { return errorExecResult(vterrors.Wrapf(err, "CheckKeyspaceLocked in ApplySchemaKeyspace %v", exec.keyspace)) } execResult.CurSQLIndex = index diff --git a/go/vt/topo/keyspace_lock.go b/go/vt/topo/keyspace_lock.go new file mode 100644 index 00000000000..7df1b2ee64f --- /dev/null +++ b/go/vt/topo/keyspace_lock.go @@ -0,0 +1,58 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package topo + +import ( + "context" + "path" +) + +type keyspaceLock struct { + keyspace string +} + +var _ iTopoLock = (*keyspaceLock)(nil) + +func (s *keyspaceLock) Type() string { + return "keyspace" +} + +func (s *keyspaceLock) ResourceName() string { + return s.keyspace +} + +func (s *keyspaceLock) Path() string { + return path.Join(KeyspacesPath, s.keyspace) +} + +// LockKeyspace will lock the keyspace, and return: +// - a context with a locksInfo structure for future reference. +// - an unlock method +// - an error if anything failed. +func (ts *Server) LockKeyspace(ctx context.Context, keyspace, action string) (context.Context, func(*error), error) { + return ts.internalLock(ctx, &keyspaceLock{ + keyspace: keyspace, + }, action, true) +} + +// CheckKeyspaceLocked can be called on a context to make sure we have the lock +// for a given keyspace. +func CheckKeyspaceLocked(ctx context.Context, keyspace string) error { + return checkLocked(ctx, &keyspaceLock{ + keyspace: keyspace, + }) +} diff --git a/go/vt/topo/keyspace_lock_test.go b/go/vt/topo/keyspace_lock_test.go new file mode 100644 index 00000000000..6d0a34de554 --- /dev/null +++ b/go/vt/topo/keyspace_lock_test.go @@ -0,0 +1,84 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package topo_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" +) + +// TestTopoKeyspaceLock tests keyspace lock operations. +func TestTopoKeyspaceLock(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ts := memorytopo.NewServer(ctx, "zone1") + defer ts.Close() + + currentTopoLockTimeout := topo.LockTimeout + topo.LockTimeout = testLockTimeout + defer func() { + topo.LockTimeout = currentTopoLockTimeout + }() + + ks1 := "ks1" + ks2 := "ks2" + err := ts.CreateKeyspace(ctx, ks1, &topodatapb.Keyspace{}) + require.NoError(t, err) + err = ts.CreateKeyspace(ctx, ks2, &topodatapb.Keyspace{}) + require.NoError(t, err) + + origCtx := ctx + ctx, unlock, err := ts.LockKeyspace(origCtx, ks1, "ks1") + require.NoError(t, err) + + // locking the same key again, without unlocking, should return an error + _, _, err2 := ts.LockKeyspace(ctx, ks1, "ks1") + require.ErrorContains(t, err2, "already held") + + // Check that we have the keyspace lock shouldn't return an error + err = topo.CheckKeyspaceLocked(ctx, ks1) + require.NoError(t, err) + + // Check that we have the keyspace lock for the other keyspace should return an error + err = topo.CheckKeyspaceLocked(ctx, ks2) + require.ErrorContains(t, err, "keyspace ks2 is not locked") + + // Check we can acquire a keyspace lock for the other keyspace + ctx2, unlock2, err := ts.LockKeyspace(ctx, ks2, "ks2") + require.NoError(t, err) + defer unlock2(&err) + + // Unlock the first keyspace + unlock(&err) + + // Check keyspace locked output for both keyspaces + err = topo.CheckKeyspaceLocked(ctx2, ks1) + require.ErrorContains(t, err, "keyspace ks1 is not locked") + err = topo.CheckKeyspaceLocked(ctx2, ks2) + require.NoError(t, err) + + // confirm that the lock can be re-acquired after unlocking + _, unlock, err = ts.LockKeyspace(origCtx, ks1, "ks1") + require.NoError(t, err) + defer unlock(&err) +} diff --git a/go/vt/topo/locks.go b/go/vt/topo/locks.go index 040dff6ea91..16caaf49dfb 100644 --- a/go/vt/topo/locks.go +++ b/go/vt/topo/locks.go @@ -21,13 +21,11 @@ import ( "encoding/json" "os" "os/user" - "path" "sync" "time" "github.com/spf13/pflag" - _flag "vitess.io/vitess/go/internal/flag" "vitess.io/vitess/go/trace" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/proto/vtrpc" @@ -35,8 +33,7 @@ import ( "vitess.io/vitess/go/vt/vterrors" ) -// This file contains utility methods and definitions to lock -// keyspaces and shards. +// This file contains utility methods and definitions to lock resources using topology server. var ( // LockTimeout is the maximum duration for which a @@ -123,131 +120,37 @@ type locksKeyType int var locksKey locksKeyType -// LockKeyspace will lock the keyspace, and return: -// - a context with a locksInfo structure for future reference. -// - an unlock method -// - an error if anything failed. -func (ts *Server) LockKeyspace(ctx context.Context, keyspace, action string) (context.Context, func(*error), error) { - i, ok := ctx.Value(locksKey).(*locksInfo) - if !ok { - i = &locksInfo{ - info: make(map[string]*lockInfo), - } - ctx = context.WithValue(ctx, locksKey, i) - } - i.mu.Lock() - defer i.mu.Unlock() - - // check that we're not already locked - if _, ok = i.info[keyspace]; ok { - return nil, nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "lock for keyspace %v is already held", keyspace) - } - - // lock - l := newLock(action) - lockDescriptor, err := l.lockKeyspace(ctx, ts, keyspace) - if err != nil { - return nil, nil, err - } - - // and update our structure - i.info[keyspace] = &lockInfo{ - lockDescriptor: lockDescriptor, - actionNode: l, - } - return ctx, func(finalErr *error) { - i.mu.Lock() - defer i.mu.Unlock() - - if _, ok := i.info[keyspace]; !ok { - if *finalErr != nil { - log.Errorf("trying to unlock keyspace %v multiple times", keyspace) - } else { - *finalErr = vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "trying to unlock keyspace %v multiple times", keyspace) - } - return - } - - err := l.unlockKeyspace(ctx, ts, keyspace, lockDescriptor, *finalErr) - if *finalErr != nil { - if err != nil { - // both error are set, just log the unlock error - log.Errorf("unlockKeyspace(%v) failed: %v", keyspace, err) - } - } else { - *finalErr = err - } - delete(i.info, keyspace) - }, nil +// iTopoLock is the interface for knowing the resource that is being locked. +// It allows for better controlling nuances for different lock types and log messages. +type iTopoLock interface { + Type() string + ResourceName() string + Path() string } -// CheckKeyspaceLocked can be called on a context to make sure we have the lock -// for a given keyspace. -func CheckKeyspaceLocked(ctx context.Context, keyspace string) error { - // extract the locksInfo pointer - i, ok := ctx.Value(locksKey).(*locksInfo) - if !ok { - return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "keyspace %v is not locked (no locksInfo)", keyspace) - } - i.mu.Lock() - defer i.mu.Unlock() - - // find the individual entry - _, ok = i.info[keyspace] - if !ok { - return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "keyspace %v is not locked (no lockInfo in map)", keyspace) - } - - // TODO(alainjobart): check the lock server implementation - // still holds the lock. Will need to look at the lockInfo struct. - - // and we're good for now. - return nil -} - -// CheckKeyspaceLockedAndRenew can be called on a context to make sure we have the lock -// for a given keyspace. The function also attempts to renew the lock. -func CheckKeyspaceLockedAndRenew(ctx context.Context, keyspace string) error { - // extract the locksInfo pointer - i, ok := ctx.Value(locksKey).(*locksInfo) - if !ok { - return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "keyspace %v is not locked (no locksInfo)", keyspace) - } - i.mu.Lock() - defer i.mu.Unlock() +// perform the topo lock operation +func (l *Lock) lock(ctx context.Context, ts *Server, lt iTopoLock, isBlocking bool) (LockDescriptor, error) { + log.Infof("Locking %v %v for action %v", lt.Type(), lt.ResourceName(), l.Action) - // find the individual entry - entry, ok := i.info[keyspace] - if !ok { - return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "keyspace %v is not locked (no lockInfo in map)", keyspace) - } - // try renewing lease: - return entry.lockDescriptor.Check(ctx) -} - -// lockKeyspace will lock the keyspace in the topology server. -// unlockKeyspace should be called if this returns no error. -func (l *Lock) lockKeyspace(ctx context.Context, ts *Server, keyspace string) (LockDescriptor, error) { - log.Infof("Locking keyspace %v for action %v", keyspace, l.Action) - - ctx, cancel := context.WithTimeout(ctx, getLockTimeout()) + ctx, cancel := context.WithTimeout(ctx, LockTimeout) defer cancel() - - span, ctx := trace.NewSpan(ctx, "TopoServer.LockKeyspaceForAction") + span, ctx := trace.NewSpan(ctx, "TopoServer.Lock") span.Annotate("action", l.Action) - span.Annotate("keyspace", keyspace) + span.Annotate("path", lt.Path()) defer span.Finish() - keyspacePath := path.Join(KeyspacesPath, keyspace) j, err := l.ToJSON() if err != nil { return nil, err } - return ts.globalCell.Lock(ctx, keyspacePath, j) + if isBlocking { + return ts.globalCell.Lock(ctx, lt.Path(), j) + } + return ts.globalCell.TryLock(ctx, lt.Path(), j) } -// unlockKeyspace unlocks a previously locked keyspace. -func (l *Lock) unlockKeyspace(ctx context.Context, ts *Server, keyspace string, lockDescriptor LockDescriptor, actionError error) error { +// unlock unlocks a previously locked key. +func (l *Lock) unlock(ctx context.Context, lt iTopoLock, lockDescriptor LockDescriptor, actionError error) error { // Detach from the parent timeout, but copy the trace span. // We need to still release the lock even if the parent // context timed out. @@ -255,70 +158,23 @@ func (l *Lock) unlockKeyspace(ctx context.Context, ts *Server, keyspace string, ctx, cancel := context.WithTimeout(ctx, RemoteOperationTimeout) defer cancel() - span, ctx := trace.NewSpan(ctx, "TopoServer.UnlockKeyspaceForAction") + span, ctx := trace.NewSpan(ctx, "TopoServer.Unlock") span.Annotate("action", l.Action) - span.Annotate("keyspace", keyspace) + span.Annotate("path", lt.Path()) defer span.Finish() // first update the actionNode if actionError != nil { - log.Infof("Unlocking keyspace %v for action %v with error %v", keyspace, l.Action, actionError) + log.Infof("Unlocking %v %v for action %v with error %v", lt.Type(), lt.ResourceName(), l.Action, actionError) l.Status = "Error: " + actionError.Error() } else { - log.Infof("Unlocking keyspace %v for successful action %v", keyspace, l.Action) + log.Infof("Unlocking %v %v for successful action %v", lt.Type(), lt.ResourceName(), l.Action) l.Status = "Done" } return lockDescriptor.Unlock(ctx) } -// LockShard will lock the shard, and return: -// - a context with a locksInfo structure for future reference. -// - an unlock method -// - an error if anything failed. -// -// We are currently only using this method to lock actions that would -// impact each-other. Most changes of the Shard object are done by -// UpdateShardFields, which is not locking the shard object. The -// current list of actions that lock a shard are: -// * all Vitess-controlled re-parenting operations: -// - InitShardPrimary -// - PlannedReparentShard -// - EmergencyReparentShard -// -// * any vtorc recovery e.g -// - RecoverDeadPrimary -// - ElectNewPrimary -// - FixPrimary -// -// * before any replication repair from replication manager -// -// * operations that we don't want to conflict with re-parenting: -// - DeleteTablet when it's the shard's current primary -func (ts *Server) LockShard(ctx context.Context, keyspace, shard, action string) (context.Context, func(*error), error) { - return ts.internalLockShard(ctx, keyspace, shard, action, true) -} - -// TryLockShard will lock the shard, and return: -// - a context with a locksInfo structure for future reference. -// - an unlock method -// - an error if anything failed. -// -// `TryLockShard` is different from `LockShard`. If there is already a lock on given shard, -// then unlike `LockShard` instead of waiting and blocking the client it returns with -// `Lock already exists` error. With current implementation it may not be able to fail-fast -// for some scenarios. For example there is a possibility that a thread checks for lock for -// a given shard but by the time it acquires the lock, some other thread has already acquired it, -// in this case the client will block until the other caller releases the lock or the -// client call times out (just like standard `LockShard' implementation). In short the lock checking -// and acquiring is not under the same mutex in current implementation of `TryLockShard`. -// -// We are currently using `TryLockShard` during tablet discovery in Vtorc recovery -func (ts *Server) TryLockShard(ctx context.Context, keyspace, shard, action string) (context.Context, func(*error), error) { - return ts.internalLockShard(ctx, keyspace, shard, action, false) -} - -// internalLockShard is used to indicate whether the call should fail-fast or not. -func (ts *Server) internalLockShard(ctx context.Context, keyspace, shard, action string, isBlocking bool) (context.Context, func(*error), error) { +func (ts *Server) internalLock(ctx context.Context, lt iTopoLock, action string, isBlocking bool) (context.Context, func(*error), error) { i, ok := ctx.Value(locksKey).(*locksInfo) if !ok { i = &locksInfo{ @@ -328,28 +184,19 @@ func (ts *Server) internalLockShard(ctx context.Context, keyspace, shard, action } i.mu.Lock() defer i.mu.Unlock() - - // check that we're not already locked - mapKey := keyspace + "/" + shard - if _, ok = i.info[mapKey]; ok { - return nil, nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "lock for shard %v/%v is already held", keyspace, shard) + // check that we are not already locked + if _, ok := i.info[lt.ResourceName()]; ok { + return nil, nil, vterrors.Errorf(vtrpc.Code_INTERNAL, "lock for %v %v is already held", lt.Type(), lt.ResourceName()) } - // lock + // lock it l := newLock(action) - var lockDescriptor LockDescriptor - var err error - if isBlocking { - lockDescriptor, err = l.lockShard(ctx, ts, keyspace, shard) - } else { - lockDescriptor, err = l.tryLockShard(ctx, ts, keyspace, shard) - } + lockDescriptor, err := l.lock(ctx, ts, lt, isBlocking) if err != nil { return nil, nil, err } - // and update our structure - i.info[mapKey] = &lockInfo{ + i.info[lt.ResourceName()] = &lockInfo{ lockDescriptor: lockDescriptor, actionNode: l, } @@ -357,118 +204,45 @@ func (ts *Server) internalLockShard(ctx context.Context, keyspace, shard, action i.mu.Lock() defer i.mu.Unlock() - if _, ok := i.info[mapKey]; !ok { + if _, ok := i.info[lt.ResourceName()]; !ok { if *finalErr != nil { - log.Errorf("trying to unlock shard %v/%v multiple times", keyspace, shard) + log.Errorf("trying to unlock %v %v multiple times", lt.Type(), lt.ResourceName()) } else { - *finalErr = vterrors.Errorf(vtrpc.Code_INTERNAL, "trying to unlock shard %v/%v multiple times", keyspace, shard) + *finalErr = vterrors.Errorf(vtrpc.Code_INTERNAL, "trying to unlock %v %v multiple times", lt.Type(), lt.ResourceName()) } return } - err := l.unlockShard(ctx, ts, keyspace, shard, lockDescriptor, *finalErr) + err := l.unlock(ctx, lt, lockDescriptor, *finalErr) + // if we have an error, we log it, but we still want to delete the lock if *finalErr != nil { if err != nil { // both error are set, just log the unlock error - log.Warningf("unlockShard(%s/%s) failed: %v", keyspace, shard, err) + log.Warningf("unlock %v %v failed: %v", lt.Type(), lt.ResourceName(), err) } } else { *finalErr = err } - delete(i.info, mapKey) + delete(i.info, lt.ResourceName()) }, nil } -// CheckShardLocked can be called on a context to make sure we have the lock -// for a given shard. -func CheckShardLocked(ctx context.Context, keyspace, shard string) error { +// checkLocked checks that the given resource is locked. +func checkLocked(ctx context.Context, lt iTopoLock) error { // extract the locksInfo pointer i, ok := ctx.Value(locksKey).(*locksInfo) if !ok { - return vterrors.Errorf(vtrpc.Code_INTERNAL, "shard %v/%v is not locked (no locksInfo)", keyspace, shard) + return vterrors.Errorf(vtrpc.Code_INTERNAL, "%v %v is not locked (no locksInfo)", lt.Type(), lt.ResourceName()) } i.mu.Lock() defer i.mu.Unlock() - // func the individual entry - mapKey := keyspace + "/" + shard - li, ok := i.info[mapKey] + // find the individual entry + li, ok := i.info[lt.ResourceName()] if !ok { - return vterrors.Errorf(vtrpc.Code_INTERNAL, "shard %v/%v is not locked (no lockInfo in map)", keyspace, shard) + return vterrors.Errorf(vtrpc.Code_INTERNAL, "%v %v is not locked (no lockInfo in map)", lt.Type(), lt.ResourceName()) } // Check the lock server implementation still holds the lock. return li.lockDescriptor.Check(ctx) } - -// lockShard will lock the shard in the topology server. -// UnlockShard should be called if this returns no error. -func (l *Lock) lockShard(ctx context.Context, ts *Server, keyspace, shard string) (LockDescriptor, error) { - return l.internalLockShard(ctx, ts, keyspace, shard, true) -} - -// tryLockShard will lock the shard in the topology server but unlike `lockShard` it fail-fast if not able to get lock -// UnlockShard should be called if this returns no error. -func (l *Lock) tryLockShard(ctx context.Context, ts *Server, keyspace, shard string) (LockDescriptor, error) { - return l.internalLockShard(ctx, ts, keyspace, shard, false) -} - -func (l *Lock) internalLockShard(ctx context.Context, ts *Server, keyspace, shard string, isBlocking bool) (LockDescriptor, error) { - log.Infof("Locking shard %v/%v for action %v", keyspace, shard, l.Action) - - ctx, cancel := context.WithTimeout(ctx, getLockTimeout()) - defer cancel() - - span, ctx := trace.NewSpan(ctx, "TopoServer.LockShardForAction") - span.Annotate("action", l.Action) - span.Annotate("keyspace", keyspace) - span.Annotate("shard", shard) - defer span.Finish() - - shardPath := path.Join(KeyspacesPath, keyspace, ShardsPath, shard) - j, err := l.ToJSON() - if err != nil { - return nil, err - } - if isBlocking { - return ts.globalCell.Lock(ctx, shardPath, j) - } - return ts.globalCell.TryLock(ctx, shardPath, j) -} - -// unlockShard unlocks a previously locked shard. -func (l *Lock) unlockShard(ctx context.Context, ts *Server, keyspace, shard string, lockDescriptor LockDescriptor, actionError error) error { - // Detach from the parent timeout, but copy the trace span. - // We need to still release the lock even if the parent context timed out. - ctx = trace.CopySpan(context.TODO(), ctx) - ctx, cancel := context.WithTimeout(ctx, RemoteOperationTimeout) - defer cancel() - - span, ctx := trace.NewSpan(ctx, "TopoServer.UnlockShardForAction") - span.Annotate("action", l.Action) - span.Annotate("keyspace", keyspace) - span.Annotate("shard", shard) - defer span.Finish() - - // first update the actionNode - if actionError != nil { - log.Infof("Unlocking shard %v/%v for action %v with error %v", keyspace, shard, l.Action, actionError) - l.Status = "Error: " + actionError.Error() - } else { - log.Infof("Unlocking shard %v/%v for successful action %v", keyspace, shard, l.Action) - l.Status = "Done" - } - return lockDescriptor.Unlock(ctx) -} - -// getLockTimeout is shim code used for backward compatibility with v15 -// This code can be removed in v17+ and LockTimeout can be used directly -func getLockTimeout() time.Duration { - if _flag.IsFlagProvided("lock-timeout") { - return LockTimeout - } - if _flag.IsFlagProvided("remote_operation_timeout") { - return RemoteOperationTimeout - } - return LockTimeout -} diff --git a/go/vt/topo/locks_test.go b/go/vt/topo/locks_test.go deleted file mode 100644 index c4d2019676e..00000000000 --- a/go/vt/topo/locks_test.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2022 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topo - -import ( - "os" - "testing" - "time" - - "github.com/spf13/pflag" - "github.com/stretchr/testify/require" - - "vitess.io/vitess/go/internal/flag" -) - -// TestGetLockTimeout tests the behaviour of -// getLockTimeout function in different situations where -// the two flags `remote_operation_timeout` and `lock-timeout` are -// provided or not. -func TestGetLockTimeout(t *testing.T) { - tests := []struct { - description string - lockTimeoutValue string - remoteOperationTimeoutValue string - expectedLockTimeout time.Duration - }{ - { - description: "no flags specified", - lockTimeoutValue: "", - remoteOperationTimeoutValue: "", - expectedLockTimeout: 45 * time.Second, - }, { - description: "lock-timeout flag specified", - lockTimeoutValue: "33s", - remoteOperationTimeoutValue: "", - expectedLockTimeout: 33 * time.Second, - }, { - description: "remote operation timeout flag specified", - lockTimeoutValue: "", - remoteOperationTimeoutValue: "33s", - expectedLockTimeout: 33 * time.Second, - }, { - description: "both flags specified", - lockTimeoutValue: "33s", - remoteOperationTimeoutValue: "22s", - expectedLockTimeout: 33 * time.Second, - }, { - description: "remote operation timeout flag specified to the default", - lockTimeoutValue: "", - remoteOperationTimeoutValue: "15s", - expectedLockTimeout: 15 * time.Second, - }, { - description: "lock-timeout flag specified to the default", - lockTimeoutValue: "45s", - remoteOperationTimeoutValue: "33s", - expectedLockTimeout: 45 * time.Second, - }, - } - - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - oldLockTimeout := LockTimeout - oldRemoteOpsTimeout := RemoteOperationTimeout - defer func() { - LockTimeout = oldLockTimeout - RemoteOperationTimeout = oldRemoteOpsTimeout - }() - var args []string - if tt.lockTimeoutValue != "" { - args = append(args, "--lock-timeout", tt.lockTimeoutValue) - } - if tt.remoteOperationTimeoutValue != "" { - args = append(args, "--remote_operation_timeout", tt.remoteOperationTimeoutValue) - } - os.Args = os.Args[0:1] - os.Args = append(os.Args, args...) - - fs := pflag.NewFlagSet("test", pflag.ExitOnError) - registerTopoLockFlags(fs) - flag.Parse(fs) - - val := getLockTimeout() - require.Equal(t, tt.expectedLockTimeout, val) - }) - } - -} diff --git a/go/vt/topo/routing_rules_lock.go b/go/vt/topo/routing_rules_lock.go index db4fa63bc9b..c45ddb738c9 100644 --- a/go/vt/topo/routing_rules_lock.go +++ b/go/vt/topo/routing_rules_lock.go @@ -18,20 +18,30 @@ package topo import ( "context" - "fmt" ) -// RoutingRulesLock is a wrapper over TopoLock, to serialize updates to routing rules. -type RoutingRulesLock struct { - *TopoLock +type routingRules struct{} + +var _ iTopoLock = (*routingRules)(nil) + +func (s *routingRules) Type() string { + return RoutingRulesPath +} + +func (s *routingRules) ResourceName() string { + return RoutingRulesPath +} + +func (s *routingRules) Path() string { + return RoutingRulesPath +} + +// LockRoutingRules acquires a lock for routing rules. +func (ts *Server) LockRoutingRules(ctx context.Context, action string) (context.Context, func(*error), error) { + return ts.internalLock(ctx, &routingRules{}, action, true) } -func NewRoutingRulesLock(ctx context.Context, ts *Server, name string) (*RoutingRulesLock, error) { - return &RoutingRulesLock{ - TopoLock: &TopoLock{ - Path: RoutingRulesPath, - Name: fmt.Sprintf("RoutingRules::%s", name), - ts: ts, - }, - }, nil +// CheckRoutingRulesLocked checks if a lock for routing rules is still possessed. +func CheckRoutingRulesLocked(ctx context.Context) error { + return checkLocked(ctx, &routingRules{}) } diff --git a/go/vt/topo/routing_rules_lock_test.go b/go/vt/topo/routing_rules_lock_test.go index 23027517019..2627ea8e984 100644 --- a/go/vt/topo/routing_rules_lock_test.go +++ b/go/vt/topo/routing_rules_lock_test.go @@ -19,6 +19,7 @@ package topo_test import ( "context" "testing" + "time" "github.com/stretchr/testify/require" @@ -28,6 +29,61 @@ import ( vschemapb "vitess.io/vitess/go/vt/proto/vschema" ) +// lower the lock timeout for testing +const testLockTimeout = 3 * time.Second + +// TestTopoLockTimeout tests that the lock times out after the specified duration. +func TestTopoLockTimeout(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ts := memorytopo.NewServer(ctx, "zone1") + defer ts.Close() + + err := ts.CreateKeyspaceRoutingRules(ctx, &vschemapb.KeyspaceRoutingRules{}) + require.NoError(t, err) + + currentTopoLockTimeout := topo.LockTimeout + topo.LockTimeout = testLockTimeout + defer func() { + topo.LockTimeout = currentTopoLockTimeout + }() + + // acquire the lock + origCtx := ctx + _, unlock, err := ts.LockRoutingRules(origCtx, "ks1") + require.NoError(t, err) + defer unlock(&err) + + // re-acquiring the lock should fail + _, _, err2 := ts.LockRoutingRules(origCtx, "ks1") + require.Errorf(t, err2, "deadline exceeded") +} + +// TestTopoLockBasic tests basic lock operations. +func TestTopoLockBasic(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ts := memorytopo.NewServer(ctx, "zone1") + defer ts.Close() + + err := ts.CreateKeyspaceRoutingRules(ctx, &vschemapb.KeyspaceRoutingRules{}) + require.NoError(t, err) + + origCtx := ctx + ctx, unlock, err := ts.LockRoutingRules(origCtx, "ks1") + require.NoError(t, err) + + // locking the same key again, without unlocking, should return an error + _, _, err2 := ts.LockRoutingRules(ctx, "ks1") + require.ErrorContains(t, err2, "already held") + + // confirm that the lock can be re-acquired after unlocking + unlock(&err) + _, unlock, err = ts.LockRoutingRules(origCtx, "ks1") + require.NoError(t, err) + defer unlock(&err) +} + // TestKeyspaceRoutingRulesLock tests that the lock is acquired and released correctly. func TestKeyspaceRoutingRulesLock(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) @@ -44,18 +100,16 @@ func TestKeyspaceRoutingRulesLock(t *testing.T) { err := ts.CreateKeyspaceRoutingRules(ctx, &vschemapb.KeyspaceRoutingRules{}) require.NoError(t, err) - lock, err := topo.NewRoutingRulesLock(ctx, ts, "ks1") - require.NoError(t, err) - _, unlock, err := lock.Lock(ctx) + _, unlock, err := ts.LockRoutingRules(ctx, "ks1") require.NoError(t, err) // re-acquiring the lock should fail - _, _, err = lock.Lock(ctx) + _, _, err = ts.LockRoutingRules(ctx, "ks1") require.Error(t, err) unlock(&err) // re-acquiring the lock should succeed - _, _, err = lock.Lock(ctx) + _, _, err = ts.LockRoutingRules(ctx, "ks1") require.NoError(t, err) } diff --git a/go/vt/topo/shard_lock.go b/go/vt/topo/shard_lock.go new file mode 100644 index 00000000000..72d0b1c8ca4 --- /dev/null +++ b/go/vt/topo/shard_lock.go @@ -0,0 +1,98 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package topo + +import ( + "context" + "path" +) + +type shardLock struct { + keyspace, shard string +} + +var _ iTopoLock = (*shardLock)(nil) + +func (s *shardLock) Type() string { + return "shard" +} + +func (s *shardLock) ResourceName() string { + return s.keyspace + "/" + s.shard +} + +func (s *shardLock) Path() string { + return path.Join(KeyspacesPath, s.keyspace, ShardsPath, s.shard) +} + +// LockShard will lock the shard, and return: +// - a context with a locksInfo structure for future reference. +// - an unlock method +// - an error if anything failed. +// +// We are currently only using this method to lock actions that would +// impact each-other. Most changes of the Shard object are done by +// UpdateShardFields, which is not locking the shard object. The +// current list of actions that lock a shard are: +// * all Vitess-controlled re-parenting operations: +// - PlannedReparentShard +// - EmergencyReparentShard +// +// * any vtorc recovery e.g +// - RecoverDeadPrimary +// - ElectNewPrimary +// - FixPrimary +// +// * operations that we don't want to conflict with re-parenting: +// - DeleteTablet when it's the shard's current primary +func (ts *Server) LockShard(ctx context.Context, keyspace, shard, action string) (context.Context, func(*error), error) { + return ts.internalLock(ctx, &shardLock{ + keyspace: keyspace, + shard: shard, + }, action, true) +} + +// TryLockShard will lock the shard, and return: +// - a context with a locksInfo structure for future reference. +// - an unlock method +// - an error if anything failed. +// +// `TryLockShard` is different from `LockShard`. If there is already a lock on given shard, +// then unlike `LockShard` instead of waiting and blocking the client it returns with +// `Lock already exists` error. With current implementation it may not be able to fail-fast +// for some scenarios. For example there is a possibility that a thread checks for lock for +// a given shard but by the time it acquires the lock, some other thread has already acquired it, +// in this case the client will block until the other caller releases the lock or the +// client call times out (just like standard `LockShard' implementation). In short the lock checking +// and acquiring is not under the same mutex in current implementation of `TryLockShard`. +// +// We are currently using `TryLockShard` during tablet discovery in Vtorc recovery +func (ts *Server) TryLockShard(ctx context.Context, keyspace, shard, action string) (context.Context, func(*error), error) { + return ts.internalLock(ctx, &shardLock{ + keyspace: keyspace, + shard: shard, + }, action, false) +} + +// CheckShardLocked can be called on a context to make sure we have the lock +// for a given shard. +func CheckShardLocked(ctx context.Context, keyspace, shard string) error { + return checkLocked(ctx, &shardLock{ + keyspace: keyspace, + shard: shard, + }) +} diff --git a/go/vt/topo/topo_lock_test.go b/go/vt/topo/shard_lock_test.go similarity index 57% rename from go/vt/topo/topo_lock_test.go rename to go/vt/topo/shard_lock_test.go index c378c05a9ff..dd37335c4ca 100644 --- a/go/vt/topo/topo_lock_test.go +++ b/go/vt/topo/shard_lock_test.go @@ -19,71 +19,66 @@ package topo_test import ( "context" "testing" - "time" "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" - - vschemapb "vitess.io/vitess/go/vt/proto/vschema" ) -// lower the lock timeout for testing -const testLockTimeout = 3 * time.Second - -// TestTopoLockTimeout tests that the lock times out after the specified duration. -func TestTopoLockTimeout(t *testing.T) { +// TestTopoShardLock tests shard lock operations. +func TestTopoShardLock(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() ts := memorytopo.NewServer(ctx, "zone1") defer ts.Close() - err := ts.CreateKeyspaceRoutingRules(ctx, &vschemapb.KeyspaceRoutingRules{}) - require.NoError(t, err) - lock, err := topo.NewRoutingRulesLock(ctx, ts, "ks1") - require.NoError(t, err) - currentTopoLockTimeout := topo.LockTimeout topo.LockTimeout = testLockTimeout defer func() { topo.LockTimeout = currentTopoLockTimeout }() - // acquire the lock - origCtx := ctx - _, unlock, err := lock.Lock(origCtx) - require.NoError(t, err) - defer unlock(&err) - - // re-acquiring the lock should fail - _, _, err2 := lock.Lock(origCtx) - require.Errorf(t, err2, "deadline exceeded") -} - -// TestTopoLockBasic tests basic lock operations. -func TestTopoLockBasic(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - ts := memorytopo.NewServer(ctx, "zone1") - defer ts.Close() - - err := ts.CreateKeyspaceRoutingRules(ctx, &vschemapb.KeyspaceRoutingRules{}) + ks := "ks" + shard1 := "80-" + shard2 := "-80" + _, err := ts.GetOrCreateShard(ctx, ks, shard1) require.NoError(t, err) - lock, err := topo.NewRoutingRulesLock(ctx, ts, "ks1") + _, err = ts.GetOrCreateShard(ctx, ks, shard2) require.NoError(t, err) origCtx := ctx - ctx, unlock, err := lock.Lock(origCtx) + ctx, unlock, err := ts.LockShard(origCtx, ks, shard1, "ks80-") require.NoError(t, err) // locking the same key again, without unlocking, should return an error - _, _, err2 := lock.Lock(ctx) + _, _, err2 := ts.LockShard(ctx, ks, shard1, "ks80-") require.ErrorContains(t, err2, "already held") - // confirm that the lock can be re-acquired after unlocking + // Check that we have the shard lock shouldn't return an error + err = topo.CheckShardLocked(ctx, ks, shard1) + require.NoError(t, err) + + // Check that we have the shard lock for the other shard should return an error + err = topo.CheckShardLocked(ctx, ks, shard2) + require.ErrorContains(t, err, "shard ks/-80 is not locked") + + // Check we can acquire a shard lock for the other shard + ctx2, unlock2, err := ts.LockShard(ctx, ks, shard2, "ks-80") + require.NoError(t, err) + defer unlock2(&err) + + // Unlock the first shard unlock(&err) - _, unlock, err = lock.Lock(origCtx) + + // Check shard locked output for both shards + err = topo.CheckShardLocked(ctx2, ks, shard1) + require.ErrorContains(t, err, "shard ks/80- is not locked") + err = topo.CheckShardLocked(ctx2, ks, shard2) + require.NoError(t, err) + + // confirm that the lock can be re-acquired after unlocking + _, unlock, err = ts.TryLockShard(origCtx, ks, shard1, "ks80-") require.NoError(t, err) defer unlock(&err) } diff --git a/go/vt/topo/shard_test.go b/go/vt/topo/shard_test.go index 5e30a8aad2a..6bd4aae5b62 100644 --- a/go/vt/topo/shard_test.go +++ b/go/vt/topo/shard_test.go @@ -78,12 +78,29 @@ func TestRemoveCellsFromList(t *testing.T) { } } +// fakeLockDescriptor implements the topo.LockDescriptor interface +type fakeLockDescriptor struct{} + +// Check implements the topo.LockDescriptor interface +func (f fakeLockDescriptor) Check(ctx context.Context) error { + return nil +} + +// Unlock implements the topo.LockDescriptor interface +func (f fakeLockDescriptor) Unlock(ctx context.Context) error { + return nil +} + +var _ LockDescriptor = (*fakeLockDescriptor)(nil) + func lockedKeyspaceContext(keyspace string) context.Context { ctx := context.Background() return context.WithValue(ctx, locksKey, &locksInfo{ info: map[string]*lockInfo{ // An empty entry is good enough for this. - keyspace: {}, + keyspace: { + lockDescriptor: fakeLockDescriptor{}, + }, }, }) } diff --git a/go/vt/topo/topo_lock.go b/go/vt/topo/topo_lock.go deleted file mode 100644 index ffd732fff36..00000000000 --- a/go/vt/topo/topo_lock.go +++ /dev/null @@ -1,169 +0,0 @@ -/* -Copyright 2024 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topo - -import ( - "context" - "fmt" - - "vitess.io/vitess/go/trace" - "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/vterrors" -) - -// ITopoLock is the interface for a lock that can be used to lock a key in the topology server. -// The lock is associated with a context and can be unlocked by calling the returned function. -// Note that we don't need an Unlock method on the interface, as the Lock() function -// returns a function that can be used to unlock the lock. -type ITopoLock interface { - Lock(ctx context.Context) (context.Context, func(*error), error) -} - -type TopoLock struct { - Path string // topo path to lock - Name string // name, for logging purposes - - ts *Server -} - -var _ ITopoLock = (*TopoLock)(nil) - -func (ts *Server) NewTopoLock(path, name string) *TopoLock { - return &TopoLock{ - ts: ts, - Path: path, - Name: name, - } -} - -func (tl *TopoLock) String() string { - return fmt.Sprintf("TopoLock{Path: %v, Name: %v}", tl.Path, tl.Name) -} - -// perform the topo lock operation -func (l *Lock) lock(ctx context.Context, ts *Server, path string) (LockDescriptor, error) { - ctx, cancel := context.WithTimeout(ctx, LockTimeout) - defer cancel() - span, ctx := trace.NewSpan(ctx, "TopoServer.Lock") - span.Annotate("action", l.Action) - span.Annotate("path", path) - defer span.Finish() - - j, err := l.ToJSON() - if err != nil { - return nil, err - } - return ts.globalCell.Lock(ctx, path, j) -} - -// unlock unlocks a previously locked key. -func (l *Lock) unlock(ctx context.Context, path string, lockDescriptor LockDescriptor, actionError error) error { - // Detach from the parent timeout, but copy the trace span. - // We need to still release the lock even if the parent - // context timed out. - ctx = trace.CopySpan(context.TODO(), ctx) - ctx, cancel := context.WithTimeout(ctx, RemoteOperationTimeout) - defer cancel() - - span, ctx := trace.NewSpan(ctx, "TopoServer.Unlock") - span.Annotate("action", l.Action) - span.Annotate("path", path) - defer span.Finish() - - // first update the actionNode - if actionError != nil { - l.Status = "Error: " + actionError.Error() - } else { - l.Status = "Done" - } - return lockDescriptor.Unlock(ctx) -} - -// Lock adds lock information to the context, checks that the lock is not already held, and locks it. -// It returns a new context with the lock information and a function to unlock the lock. -func (tl TopoLock) Lock(ctx context.Context) (context.Context, func(*error), error) { - i, ok := ctx.Value(locksKey).(*locksInfo) - if !ok { - i = &locksInfo{ - info: make(map[string]*lockInfo), - } - ctx = context.WithValue(ctx, locksKey, i) - } - i.mu.Lock() - defer i.mu.Unlock() - // check that we are not already locked - if _, ok := i.info[tl.Path]; ok { - return nil, nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "lock for %v is already held", tl.Path) - } - - // lock it - l := newLock(fmt.Sprintf("lock for %s", tl.Name)) - lockDescriptor, err := l.lock(ctx, tl.ts, tl.Path) - if err != nil { - return nil, nil, err - } - // and update our structure - i.info[tl.Path] = &lockInfo{ - lockDescriptor: lockDescriptor, - actionNode: l, - } - return ctx, func(finalErr *error) { - i.mu.Lock() - defer i.mu.Unlock() - - if _, ok := i.info[tl.Path]; !ok { - if *finalErr != nil { - log.Errorf("trying to unlock %v multiple times", tl.Path) - } else { - *finalErr = vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "trying to unlock %v multiple times", tl.Path) - } - return - } - - err := l.unlock(ctx, tl.Path, lockDescriptor, *finalErr) - // if we have an error, we log it, but we still want to delete the lock - if *finalErr != nil { - if err != nil { - // both error are set, just log the unlock error - log.Errorf("unlock(%v) failed: %v", tl.Path, err) - } - } else { - *finalErr = err - } - delete(i.info, tl.Path) - }, nil -} - -func CheckLocked(ctx context.Context, keyPath string) error { - // extract the locksInfo pointer - i, ok := ctx.Value(locksKey).(*locksInfo) - if !ok { - return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "%s is not locked (no locksInfo)", keyPath) - } - i.mu.Lock() - defer i.mu.Unlock() - - // find the individual entry - _, ok = i.info[keyPath] - if !ok { - return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "%s is not locked (no lockInfo in map)", keyPath) - } - - // and we're good for now. - return nil -} diff --git a/go/vt/topotools/routing_rules.go b/go/vt/topotools/routing_rules.go index a3bc5a8a957..5e423f8f55d 100644 --- a/go/vt/topotools/routing_rules.go +++ b/go/vt/topotools/routing_rules.go @@ -166,7 +166,7 @@ func buildKeyspaceRoutingRules(rules *map[string]string) *vschemapb.KeyspaceRout // saveKeyspaceRoutingRulesLocked saves the keyspace routing rules in the topo server. It expects the caller to // have acquired a RoutingRulesLock. func saveKeyspaceRoutingRulesLocked(ctx context.Context, ts *topo.Server, rules map[string]string) error { - if err := topo.CheckLocked(ctx, topo.RoutingRulesPath); err != nil { + if err := topo.CheckRoutingRulesLocked(ctx); err != nil { return err } return ts.SaveKeyspaceRoutingRules(ctx, buildKeyspaceRoutingRules(&rules)) @@ -180,12 +180,7 @@ func saveKeyspaceRoutingRulesLocked(ctx context.Context, ts *topo.Server, rules // then modify the keyspace routing rules in-place. func UpdateKeyspaceRoutingRules(ctx context.Context, ts *topo.Server, reason string, update func(ctx context.Context, rules *map[string]string) error) (err error) { - var lock *topo.RoutingRulesLock - lock, err = topo.NewRoutingRulesLock(ctx, ts, reason) - if err != nil { - return err - } - lockCtx, unlock, lockErr := lock.Lock(ctx) + lockCtx, unlock, lockErr := ts.LockRoutingRules(ctx, reason) if lockErr != nil { // If the key does not yet exist then let's create it. if !topo.IsErrType(lockErr, topo.NoNode) { diff --git a/go/vt/topotools/routing_rules_test.go b/go/vt/topotools/routing_rules_test.go index 2d4d9feacd1..6a33bbfff70 100644 --- a/go/vt/topotools/routing_rules_test.go +++ b/go/vt/topotools/routing_rules_test.go @@ -150,9 +150,7 @@ func TestSaveKeyspaceRoutingRulesLocked(t *testing.T) { }) // declare and acquire lock - lock, err := topo.NewRoutingRulesLock(ctx, ts, "test") - require.NoError(t, err) - lockCtx, unlock, err := lock.Lock(ctx) + lockCtx, unlock, err := ts.LockRoutingRules(ctx, "test") require.NoError(t, err) defer unlock(&err) From 8d69437f8731d390d6ca4b3753e935839ec4e0ff Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 12 Jun 2024 22:29:44 +0300 Subject: [PATCH 26/40] `schemadiff`: only compare column collations if of textual type (#16138) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/schemadiff/schema.go | 7 +++++++ go/vt/schemadiff/schema_test.go | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index df1e23f0ccc..3b42d6cf42d 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -444,6 +444,13 @@ func colTypeEqualForForeignKey(env *Environment, ct, pt *sqlparser.TableSpec, ch } func colCollationEqualForForeignKey(env *Environment, ct, pt *sqlparser.TableSpec, child, parent *sqlparser.ColumnType) bool { + isTextual := func(col *sqlparser.ColumnType) bool { + return charsetTypes[strings.ToLower(col.Type)] + } + if !isTextual(child) || !isTextual(parent) { + // irrelevant if columns are not textual + return true + } return *colCollation(env, ct, child) == *colCollation(env, pt, parent) } diff --git a/go/vt/schemadiff/schema_test.go b/go/vt/schemadiff/schema_test.go index c35cc224714..8a4f54269cd 100644 --- a/go/vt/schemadiff/schema_test.go +++ b/go/vt/schemadiff/schema_test.go @@ -412,6 +412,28 @@ func TestInvalidSchema(t *testing.T) { create table t13 (id int primary key, i int, key i_idx (i), constraint f1307 foreign key (i) references t11 (i)); `, }, + { + schema: ` + CREATE TABLE t1 (id int NOT NULL AUTO_INCREMENT, primary key (id)); + CREATE TABLE t2 ( + id int NOT NULL AUTO_INCREMENT, + t1id int NOT NULL, + primary key (id), + CONSTRAINT fk1_en9z857fmvhhyrzb1p7lr751o FOREIGN KEY (t1id) REFERENCES t1 (id) ON DELETE CASCADE + ); + `, + }, + { + schema: ` + CREATE TABLE t1 (id int NOT NULL AUTO_INCREMENT, primary key (id)) CHARSET utf8mb4, COLLATE utf8mb4_unicode_ci; + CREATE TABLE t2 ( + id int NOT NULL AUTO_INCREMENT, + t1id int NOT NULL, + primary key (id), + CONSTRAINT fk1_en9z857fmvhhyrzb1p7lr751o FOREIGN KEY (t1id) REFERENCES t1 (id) ON DELETE CASCADE + ) CHARSET utf8mb4, COLLATE utf8mb4_0900_ai_ci; + `, + }, { schema: "create table t11 (id int primary key, i int, key ix(i), constraint f11 foreign key (i) references t11(id2) on delete restrict)", expectErr: &InvalidReferencedColumnInForeignKeyConstraintError{Table: "t11", Constraint: "f11", ReferencedTable: "t11", ReferencedColumn: "id2"}, From e907c42ad6be90bb63972166ec4c7bd2630358d2 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 13 Jun 2024 08:48:58 +0300 Subject: [PATCH 27/40] [main] Copy `v20.0.0-RC1` release notes (#16140) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- changelog/20.0/20.0.0/changelog.md | 530 +++++++++++++++++++++++++ changelog/20.0/20.0.0/release_notes.md | 369 +++++++++++++++++ changelog/20.0/README.md | 2 + 3 files changed, 901 insertions(+) create mode 100644 changelog/20.0/20.0.0/changelog.md create mode 100644 changelog/20.0/20.0.0/release_notes.md diff --git a/changelog/20.0/20.0.0/changelog.md b/changelog/20.0/20.0.0/changelog.md new file mode 100644 index 00000000000..4ee6cf6b298 --- /dev/null +++ b/changelog/20.0/20.0.0/changelog.md @@ -0,0 +1,530 @@ +# Changelog of Vitess v20.0.0 + +### Announcement +#### Governance + * add Tim Vaillancourt to maintainers [#15851](https://github.com/vitessio/vitess/pull/15851) +### Bug fixes +#### Authn/z + * Load `--grpc_auth_static_client_creds` file once [#15030](https://github.com/vitessio/vitess/pull/15030) +#### Backup and Restore + * Mysqld: capture mysqlbinlog std error output [#15278](https://github.com/vitessio/vitess/pull/15278) + * fix backup goroutine leak [#15410](https://github.com/vitessio/vitess/pull/15410) + * Ensure that WithParams keeps the transport [#15421](https://github.com/vitessio/vitess/pull/15421) + * Configurable incremental restore files path [#15451](https://github.com/vitessio/vitess/pull/15451) +#### Build/CI + * Use latest go version in update golang version workflow [#15159](https://github.com/vitessio/vitess/pull/15159) + * Fix `docker_build_images` CI workflow [#15635](https://github.com/vitessio/vitess/pull/15635) + * Continue building base/k8s when tag version is below v20 [#15638](https://github.com/vitessio/vitess/pull/15638) +#### CLI + * Fix some binaries to print the versions [#15306](https://github.com/vitessio/vitess/pull/15306) + * tablet: remove max-waiters setting [#15323](https://github.com/vitessio/vitess/pull/15323) +#### Cluster management + * Fix PromoteReplica call in ERS [#15934](https://github.com/vitessio/vitess/pull/15934) + * Remove the default for replica-net-timeout [#15938](https://github.com/vitessio/vitess/pull/15938) +#### Docker + * Add `mysqlbinlog` and `xtrabackup` to the `vitess/lite` image [#15775](https://github.com/vitessio/vitess/pull/15775) +#### Evalengine + * Fix type coercion between the sides of an UNION [#15340](https://github.com/vitessio/vitess/pull/15340) + * evalengine: Ensure to pass down the precision [#15611](https://github.com/vitessio/vitess/pull/15611) + * evalengine: Fix additional time type handling [#15614](https://github.com/vitessio/vitess/pull/15614) + * projection: Return correct collation information [#15801](https://github.com/vitessio/vitess/pull/15801) +#### General + * `ExecuteFetch`: error on multiple result sets [#14949](https://github.com/vitessio/vitess/pull/14949) + * GRPC: Address potential segfault in dedicated connection pooling [#15751](https://github.com/vitessio/vitess/pull/15751) + * Properly unescape keyspace name in FindAllShardsInKeyspace [#15765](https://github.com/vitessio/vitess/pull/15765) +#### Online DDL + * VReplication/OnlineDDL: reordering enum values [#15103](https://github.com/vitessio/vitess/pull/15103) + * Remove `ALGORITHM=COPY` from Online DDL in MySQL `>= 8.0.32` [#15376](https://github.com/vitessio/vitess/pull/15376) + * Enum value parsing: do not parse by whitespace [#15493](https://github.com/vitessio/vitess/pull/15493) + * Flaky test TestOnlineDDLVDiff: add additional check for vreplication workflow to exist [#15695](https://github.com/vitessio/vitess/pull/15695) + * `schemadiff`: `DROP COLUMN` not eligible for `INSTANT` algorithm if covered by an index [#15714](https://github.com/vitessio/vitess/pull/15714) + * `schemadiff` INSTANT DDL: impossible changes on tables with `FULLTEXT` index [#15725](https://github.com/vitessio/vitess/pull/15725) + * SchemaEngine: Ensure GetTableForPos returns table schema for "current" position by default [#15912](https://github.com/vitessio/vitess/pull/15912) +#### Query Serving + * Make connection killing resilient to MySQL hangs [#14500](https://github.com/vitessio/vitess/pull/14500) + * TxThrottler: dont throttle unless lag [#14789](https://github.com/vitessio/vitess/pull/14789) + * Planner Bug: Joins inside derived table [#14974](https://github.com/vitessio/vitess/pull/14974) + * fix: ignore internal tables in schema tracking [#15141](https://github.com/vitessio/vitess/pull/15141) + * bugfix: wrong field type returned for SUM [#15192](https://github.com/vitessio/vitess/pull/15192) + * Avoid rewriting unsharded queries and split semantic analysis in two [#15217](https://github.com/vitessio/vitess/pull/15217) + * Fix Delete with multi-tables related by foreign keys [#15218](https://github.com/vitessio/vitess/pull/15218) + * sqlparser: use integers instead of literals for Length/Precision [#15256](https://github.com/vitessio/vitess/pull/15256) + * Fix Go routine leaks in streaming calls [#15293](https://github.com/vitessio/vitess/pull/15293) + * Column alias expanding on ORDER BY [#15302](https://github.com/vitessio/vitess/pull/15302) + * planner: support union statements with ctes [#15312](https://github.com/vitessio/vitess/pull/15312) + * go/vt/discovery: use protobuf getters for SrvVschema [#15343](https://github.com/vitessio/vitess/pull/15343) + * Bugfix: GROUP BY/HAVING alias resolution [#15344](https://github.com/vitessio/vitess/pull/15344) + * SHOW VITESS_REPLICATION_STATUS: Only use replication tracker when it's enabled [#15348](https://github.com/vitessio/vitess/pull/15348) + * Fixing Column aliases in outer join queries [#15384](https://github.com/vitessio/vitess/pull/15384) + * Fix view tracking on sharded keyspace [#15436](https://github.com/vitessio/vitess/pull/15436) + * engine: fix race in concatenate [#15454](https://github.com/vitessio/vitess/pull/15454) + * Fix cycle detection for foreign keys [#15458](https://github.com/vitessio/vitess/pull/15458) + * fail insert when primary vindex cannot be mapped to a shard [#15500](https://github.com/vitessio/vitess/pull/15500) + * Fix aliasing in routes that have a derived table [#15550](https://github.com/vitessio/vitess/pull/15550) + * bugfix: handling of ANDed join predicates [#15551](https://github.com/vitessio/vitess/pull/15551) + * Make sure derived table column names are handled correctly [#15588](https://github.com/vitessio/vitess/pull/15588) + * Fix TPCH test by providing the correct field information in evalengine [#15623](https://github.com/vitessio/vitess/pull/15623) + * fix: don't forget DISTINCT for derived tables [#15672](https://github.com/vitessio/vitess/pull/15672) + * Prevent adding to query details after unserve common has started [#15684](https://github.com/vitessio/vitess/pull/15684) + * Fix panic in aggregation [#15728](https://github.com/vitessio/vitess/pull/15728) + * fix: use correct flag field for udf tracking [#15749](https://github.com/vitessio/vitess/pull/15749) + * Store Decimal precision and size while normalising [#15785](https://github.com/vitessio/vitess/pull/15785) + * Fix Scale and length handling in `CASE` and JOIN bind variables [#15787](https://github.com/vitessio/vitess/pull/15787) + * Fix derived table bug [#15831](https://github.com/vitessio/vitess/pull/15831) + * Fix CTE query by fixing bindvar pushing in unions [#15838](https://github.com/vitessio/vitess/pull/15838) + * Fix wrong assignment to `sql_id_opt` in the parser [#15862](https://github.com/vitessio/vitess/pull/15862) + * `schemadiff`: more `INSTANT` DDL compliance [#15871](https://github.com/vitessio/vitess/pull/15871) + * fix: handle info_schema routing [#15899](https://github.com/vitessio/vitess/pull/15899) + * fix: handle table_schema = '' without failing [#15901](https://github.com/vitessio/vitess/pull/15901) + * Fix aliasing in queries by keeping required projections [#15943](https://github.com/vitessio/vitess/pull/15943) + * connpool: Allow time out during shutdown [#15979](https://github.com/vitessio/vitess/pull/15979) + * `schemadiff`: assume default collation for textual column when collation is undefined [#16000](https://github.com/vitessio/vitess/pull/16000) + * fix: remove keyspace when merging subqueries [#16019](https://github.com/vitessio/vitess/pull/16019) +#### TabletManager + * mysqlctl: Improve handling of the lock file [#15404](https://github.com/vitessio/vitess/pull/15404) + * Fix possible race in MySQL startup and vttablet in parallel [#15538](https://github.com/vitessio/vitess/pull/15538) + * mysqlctld: setup a different default for onterm_timeout [#15575](https://github.com/vitessio/vitess/pull/15575) + * Fix the race condition during vttablet startup [#15731](https://github.com/vitessio/vitess/pull/15731) +#### Throttler + * Throttler: fix nil pointer dereference error [#15180](https://github.com/vitessio/vitess/pull/15180) + * Tablet throttler: starvation fix and consolidation of logic. [#15398](https://github.com/vitessio/vitess/pull/15398) + * Dedicated poolDialer logic for VTOrc, throttler [#15562](https://github.com/vitessio/vitess/pull/15562) + * Tablet throttler: recent check diff fix [#16001](https://github.com/vitessio/vitess/pull/16001) + * `ApplySchema`: reroute `ALTER VITESS_MIGRATION ... THROTTLE ...` via `UpdateThrottlerConfig` [#16030](https://github.com/vitessio/vitess/pull/16030) +#### Topology + * discovery: Fix tablets removed from healthcheck when topo server GetTablet call fails [#15633](https://github.com/vitessio/vitess/pull/15633) + * Fix ZooKeeper Topology connection locks not being cleaned up correctly [#15757](https://github.com/vitessio/vitess/pull/15757) +#### VReplication + * VReplication: disable foreign_key_checks for bulk data cleanup [#15261](https://github.com/vitessio/vitess/pull/15261) + * VReplication: Make Target Sequence Initialization More Robust [#15289](https://github.com/vitessio/vitess/pull/15289) + * MoveTables Atomic Mode: set FK checks off while deploying schema on targets [#15448](https://github.com/vitessio/vitess/pull/15448) + * VReplication: Fix workflow filtering in GetWorkflows RPC [#15524](https://github.com/vitessio/vitess/pull/15524) + * VReplication: Migrate intra-keyspace materialize workflows when Resharding the keyspace [#15536](https://github.com/vitessio/vitess/pull/15536) + * VReplication: Fix workflow update changed handling [#15621](https://github.com/vitessio/vitess/pull/15621) + * VReplication: Improve query buffering behavior during MoveTables traffic switching [#15701](https://github.com/vitessio/vitess/pull/15701) + * VReplication: Take replication lag into account in VStreamManager healthcheck result processing [#15761](https://github.com/vitessio/vitess/pull/15761) + * VReplication: Improve workflow cancel/delete [#15977](https://github.com/vitessio/vitess/pull/15977) + * [release-20.0-rc] vtctldclient: Apply (Shard | Keyspace| Table) Routing Rules commands don't work (#16096) [#16125](https://github.com/vitessio/vitess/pull/16125) + * [release-20.0] vtctldclient: Apply (Shard | Keyspace| Table) Routing Rules commands don't work (#16096) [#16126](https://github.com/vitessio/vitess/pull/16126) + * [release-20.0-rc] VReplication: Improve workflow cancel/delete (#15977) [#16130](https://github.com/vitessio/vitess/pull/16130) + * [release-20.0] VReplication: Improve workflow cancel/delete (#15977) [#16131](https://github.com/vitessio/vitess/pull/16131) +#### VTAdmin + * [VTAdmin API] Fix schema cache flag, add documentation [#15704](https://github.com/vitessio/vitess/pull/15704) + * [VTAdmin] Remove vtctld web link, improve local example (#15607) [#15824](https://github.com/vitessio/vitess/pull/15824) +#### VTCombo + * Correctly set log_dir default in vtcombo [#15153](https://github.com/vitessio/vitess/pull/15153) +#### VTorc + * Use the legacy name for timeouts [#15689](https://github.com/vitessio/vitess/pull/15689) + * Add timeout to all the contexts used for RPC calls in vtorc [#15991](https://github.com/vitessio/vitess/pull/15991) +#### vtexplain + * vtexplain: Fix setting up the column information [#15275](https://github.com/vitessio/vitess/pull/15275) + * vtexplain: Ensure memory topo is set up for throttler [#15279](https://github.com/vitessio/vitess/pull/15279) +#### vttestserver + * Revert unwanted logging change to `vttestserver` [#15148](https://github.com/vitessio/vitess/pull/15148) + * use proper mysql version in the `vttestserver` images [#15235](https://github.com/vitessio/vitess/pull/15235) +#### web UI + * [VTAdmin] Remove vtctld web link, improve local example [#15607](https://github.com/vitessio/vitess/pull/15607) +### CI/Build +#### Build/CI + * CI: Use v3 of fossa-action and exclude maven [#15140](https://github.com/vitessio/vitess/pull/15140) + * mysql: move colldump to its own standalone repository [#15166](https://github.com/vitessio/vitess/pull/15166) + * Remove concurrency group for check labels workflow [#15197](https://github.com/vitessio/vitess/pull/15197) + * CI: Use FOSSA push-only token for license scans on PRs [#15222](https://github.com/vitessio/vitess/pull/15222) + * Update FOSSA license scan links [#15233](https://github.com/vitessio/vitess/pull/15233) + * Update toolchain version in go.mod [#15245](https://github.com/vitessio/vitess/pull/15245) + * statsd: Update to datadog-go v5 API [#15247](https://github.com/vitessio/vitess/pull/15247) + * Ensure to use latest golangci-lint [#15413](https://github.com/vitessio/vitess/pull/15413) + * Fix go.mod [#15416](https://github.com/vitessio/vitess/pull/15416) + * bump `github.com/golang/protobuf` to `v1.5.4` [#15426](https://github.com/vitessio/vitess/pull/15426) + * Update all actions setup to latest versions [#15443](https://github.com/vitessio/vitess/pull/15443) + * CI: Disable CodeCov GitHub Changed Files Annotations [#15447](https://github.com/vitessio/vitess/pull/15447) + * Update to latest CodeQL [#15530](https://github.com/vitessio/vitess/pull/15530) + * Generate vtctldclient RPC client code from vtctlservice protobufs on make proto [#15561](https://github.com/vitessio/vitess/pull/15561) + * Add @mattlord as CODEOWNER for vtctld[client] related things [#15870](https://github.com/vitessio/vitess/pull/15870) + * Validate go versions in Static Code Checks CI [#15932](https://github.com/vitessio/vitess/pull/15932) + * Add CODEOWNERS for tablet throttler and schemadiff [#16036](https://github.com/vitessio/vitess/pull/16036) + * [release-20.0-rc] Add DCO workflow (#16052) [#16057](https://github.com/vitessio/vitess/pull/16057) + * [release-20.0] Add DCO workflow (#16052) [#16058](https://github.com/vitessio/vitess/pull/16058) + * [release-20.0-rc] Remove DCO workaround (#16087) [#16092](https://github.com/vitessio/vitess/pull/16092) + * [release-20.0] Remove DCO workaround (#16087) [#16093](https://github.com/vitessio/vitess/pull/16093) +#### General + * [main] Upgrade the Golang version to `go1.22.1` [#15405](https://github.com/vitessio/vitess/pull/15405) + * Upgrade go version to go1.22.2 [#15642](https://github.com/vitessio/vitess/pull/15642) + * [main] Upgrade the Golang version to `go1.22.3` [#15865](https://github.com/vitessio/vitess/pull/15865) + * [release-20.0] Upgrade the Golang version to `go1.22.4` [#16060](https://github.com/vitessio/vitess/pull/16060) + * [release-20.0-rc] [release-20.0] Upgrade the Golang version to `go1.22.4` (#16060) [#16064](https://github.com/vitessio/vitess/pull/16064) +#### Online DDL + * `onlineddl_scheduler` test: fix flakiness in artifact cleanup test [#15396](https://github.com/vitessio/vitess/pull/15396) + * Online DDL: fix flaky `onlineddl_scheduler` CI test [#16011](https://github.com/vitessio/vitess/pull/16011) +#### Throttler + * CI upgrade/downgrade tests for Online DDL / throttler / vreplication flow [#16017](https://github.com/vitessio/vitess/pull/16017) +#### VReplication + * VReplication: Get workflowFlavorVtctl endtoend testing working properly again [#15636](https://github.com/vitessio/vitess/pull/15636) +#### VTAdmin + * Update VTAdmin build script [#15839](https://github.com/vitessio/vitess/pull/15839) +### Dependencies +#### General + * Update to the latest x/net [#15680](https://github.com/vitessio/vitess/pull/15680) + * Revert GRPC context changes [#15780](https://github.com/vitessio/vitess/pull/15780) + * Upgrade the Golang Dependencies [#15823](https://github.com/vitessio/vitess/pull/15823) + * Upgrade the Golang Dependencies [#15942](https://github.com/vitessio/vitess/pull/15942) +#### Observability + * Bump vitess.io/vitess from 0.16.2 to 0.17.7 in /vitess-mixin [#15918](https://github.com/vitessio/vitess/pull/15918) + * Update `github.com/Azure/go-autorest/autorest/adal` to fix Dependabot alert [#15986](https://github.com/vitessio/vitess/pull/15986) +#### VTAdmin + * Bump vite from 4.5.2 to 4.5.3 in /web/vtadmin [#15634](https://github.com/vitessio/vitess/pull/15634) + * [release-20.0-rc] Update braces package (#16115) [#16119](https://github.com/vitessio/vitess/pull/16119) + * [release-20.0] Update braces package (#16115) [#16120](https://github.com/vitessio/vitess/pull/16120) +#### web UI + * Remove highcharts dependency pt. 1 [#15970](https://github.com/vitessio/vitess/pull/15970) +### Documentation +#### Authn/z + * Add v20 changelog docs for PR #15030 [#15367](https://github.com/vitessio/vitess/pull/15367) +#### Documentation + * Fix docs for unmanaged tablets [#15437](https://github.com/vitessio/vitess/pull/15437) + * [release-20.0-rc] Changelog 20.0: Fix broken links (#16048) [#16075](https://github.com/vitessio/vitess/pull/16075) + * [release-20.0] Changelog 20.0: Fix broken links (#16048) [#16076](https://github.com/vitessio/vitess/pull/16076) +#### General + * Add Shopify to `ADOPTERS.md` [#15853](https://github.com/vitessio/vitess/pull/15853) +#### Governance + * amend contributing guide to ban trivial contributions [#15618](https://github.com/vitessio/vitess/pull/15618) + * remove koz from active maintainer list [#15733](https://github.com/vitessio/vitess/pull/15733) +#### Topology + * Add lock shard docs [#15981](https://github.com/vitessio/vitess/pull/15981) +#### VReplication + * VDiff CLI: add missing target keyspace in VDiff command examples [#15525](https://github.com/vitessio/vitess/pull/15525) +#### VTGate + * Add changelogs for PR #15911 and #15919 [#16044](https://github.com/vitessio/vitess/pull/16044) +### Enhancement +#### Backup and Restore + * Point in time recovery and restore: assume (and validate) MySQL56 flavor in position arguments [#15599](https://github.com/vitessio/vitess/pull/15599) + * mysqlctl: Improve backup restore compatibility check [#15856](https://github.com/vitessio/vitess/pull/15856) +#### Build/CI + * [main] Add `release-19.0` to the auto go upgrade (#15157) [#15168](https://github.com/vitessio/vitess/pull/15168) + * Update paths filter action [#15254](https://github.com/vitessio/vitess/pull/15254) + * Add memory check for runners for VTOrc tests [#15317](https://github.com/vitessio/vitess/pull/15317) + * Assign and tag the release team for go update/upgrade auto PRs [#15737](https://github.com/vitessio/vitess/pull/15737) +#### Cluster management + * Add unmanaged tablet flag at vttablet level [#14871](https://github.com/vitessio/vitess/pull/14871) + * Fix error message for planned reparent shard [#15529](https://github.com/vitessio/vitess/pull/15529) + * Filter tablet map using valid candidates before reparenting to intermediate source [#15540](https://github.com/vitessio/vitess/pull/15540) + * Add a default for `replica_net_timeout` [#15663](https://github.com/vitessio/vitess/pull/15663) + * Add `GetServerStatus` RPC to use in PRS [#16022](https://github.com/vitessio/vitess/pull/16022) +#### Docker + * Remove MySQL/Percona from the `vitess/lite` Docker image [#15605](https://github.com/vitessio/vitess/pull/15605) + * Remove `vitess/base` and `vitess/k8s` Docker images [#15620](https://github.com/vitessio/vitess/pull/15620) +#### Driver + * Add types to Go SQL driver [#15569](https://github.com/vitessio/vitess/pull/15569) +#### Evalengine + * evalEngine: Implement SPACE, REVERSE [#15173](https://github.com/vitessio/vitess/pull/15173) + * evalengine: Implement LOCATE and friends [#15195](https://github.com/vitessio/vitess/pull/15195) + * evalEngine: Implement string `INSERT` [#15201](https://github.com/vitessio/vitess/pull/15201) + * evalengine: Implement BIN, OCT & CHAR functions [#15226](https://github.com/vitessio/vitess/pull/15226) + * evalEngine: Implement ELT and FIELD [#15249](https://github.com/vitessio/vitess/pull/15249) + * evalengine: Implement REPLACE [#15274](https://github.com/vitessio/vitess/pull/15274) + * evalengine: Implement `TO_SECONDS` [#15590](https://github.com/vitessio/vitess/pull/15590) + * evalengine: Fix temporal cases in `MAKETIME` [#15709](https://github.com/vitessio/vitess/pull/15709) + * evalengine: Implement `SEC_TO_TIME` [#15755](https://github.com/vitessio/vitess/pull/15755) + * evalengine: Add support for enum and set [#15783](https://github.com/vitessio/vitess/pull/15783) +#### Examples + * Update `operator.yaml` and add schedule backup example [#15969](https://github.com/vitessio/vitess/pull/15969) +#### General + * Enable gRPC Server Side Keepalive settings [#14939](https://github.com/vitessio/vitess/pull/14939) +#### Observability + * queryserving, observability: instrument vttablet query cache plan hits/misses [#14947](https://github.com/vitessio/vitess/pull/14947) + * VTGate Warnings: Add `WarnUnshardedOnly` to warnings counter [#15033](https://github.com/vitessio/vitess/pull/15033) + * VDiff: Add some stats [#15175](https://github.com/vitessio/vitess/pull/15175) +#### Online DDL + * DDL strategy flag `--unsafe-allow-foreign-keys` implies setting `FOREIGN_KEY_CHECKS=0` [#15432](https://github.com/vitessio/vitess/pull/15432) + * `schemadiff`: `SubsequentDiffStrategy`: allow/reject multiple changes on same entity [#15675](https://github.com/vitessio/vitess/pull/15675) + * Online DDL: unsupporting `gh-ost` DDL strategy [#15693](https://github.com/vitessio/vitess/pull/15693) + * Online DDL: better support for range partitioning [#15698](https://github.com/vitessio/vitess/pull/15698) +#### Query Serving + * Limit concurrent creation of healthcheck gRPC connections [#15053](https://github.com/vitessio/vitess/pull/15053) + * feat: use collation aware typing for UNION [#15122](https://github.com/vitessio/vitess/pull/15122) + * Fix evalEngine functions for dates on/before `0000-02-29` [#15124](https://github.com/vitessio/vitess/pull/15124) + * Subqueries in SET condition of UPDATE statement in presence of foreign keys [#15163](https://github.com/vitessio/vitess/pull/15163) + * Feature: Adding support for Vindex Hints to allow for greater control over shard routing [#15172](https://github.com/vitessio/vitess/pull/15172) + * Fix PRS from being blocked because of misbehaving clients [#15339](https://github.com/vitessio/vitess/pull/15339) + * Filter by keyspace earlier in `tabletgateway`s `WaitForTablets(...)` [#15347](https://github.com/vitessio/vitess/pull/15347) + * Update Planning for Limits in the presence of foreign keys [#15372](https://github.com/vitessio/vitess/pull/15372) + * `schemadiff`: supporting textual diff [#15388](https://github.com/vitessio/vitess/pull/15388) + * Use a throttled logger for exceeded memory warnings [#15424](https://github.com/vitessio/vitess/pull/15424) + * `schemadiff`: support valid foreign key cycles [#15431](https://github.com/vitessio/vitess/pull/15431) + * Handle panics during parallel execution [#15450](https://github.com/vitessio/vitess/pull/15450) + * Optimize with IN Clause for UPDATE/DELETE Statements on Vindexes [#15455](https://github.com/vitessio/vitess/pull/15455) + * `schemadiff`: remove `ForeignKeyLoopError` and loop detection logic [#15507](https://github.com/vitessio/vitess/pull/15507) + * Add support for `row_alias` syntax added in MySQL 8.0.19. [#15510](https://github.com/vitessio/vitess/pull/15510) + * test: failing unit test for type aggregation [#15518](https://github.com/vitessio/vitess/pull/15518) + * Allow non-reserved-keywords for index names [#15602](https://github.com/vitessio/vitess/pull/15602) + * feat: support IS UNKNOWN as synonym to IS NULL [#15673](https://github.com/vitessio/vitess/pull/15673) + * Use Kill Query for Non-Transaction Query Execution and Update Query Timeout / Cancelled Error Message [#15694](https://github.com/vitessio/vitess/pull/15694) + * Add schema tracking support for UDFs [#15705](https://github.com/vitessio/vitess/pull/15705) + * Gen4 Planner: support aggregate UDFs [#15710](https://github.com/vitessio/vitess/pull/15710) + * Prepare schema tracking for all UDFs [#15732](https://github.com/vitessio/vitess/pull/15732) + * add udfs to vschema on update [#15771](https://github.com/vitessio/vitess/pull/15771) + * fix: make sure string literals as columns are handled well [#15820](https://github.com/vitessio/vitess/pull/15820) + * Improve `mcmp` type comparison [#15821](https://github.com/vitessio/vitess/pull/15821) + * feat: optimise outer joins [#15840](https://github.com/vitessio/vitess/pull/15840) + * `schemadiff`: atomic diffs for range partition `DROP PARTITION` statement [#15843](https://github.com/vitessio/vitess/pull/15843) + * Add error transformer to vtgate executor [#15894](https://github.com/vitessio/vitess/pull/15894) + * allow query timeout hints on shard targeting [#15898](https://github.com/vitessio/vitess/pull/15898) + * feat: add support for WITH ROLLUP [#15930](https://github.com/vitessio/vitess/pull/15930) + * `schemadiff`: ALTER TABLE is not INSTANT-able if adding column with default expression value [#16028](https://github.com/vitessio/vitess/pull/16028) +#### TabletManager + * Introducing `ExecuteMultiFetchAsDba` gRPC and `vtctldclient ExecuteMultiFetchAsDBA` command [#15506](https://github.com/vitessio/vitess/pull/15506) +#### Throttler + * VReplication: Add throttler stats [#15221](https://github.com/vitessio/vitess/pull/15221) +#### Topology + * Topo: Add version support to GetTopologyPath [#15933](https://github.com/vitessio/vitess/pull/15933) +#### VReplication + * VReplication: Enforce consistent order for table copies and diffs [#15152](https://github.com/vitessio/vitess/pull/15152) + * VReplication: use proper column collations in vstreamer [#15313](https://github.com/vitessio/vitess/pull/15313) + * VStream: Allow for automatic resume after Reshard across VStreams [#15395](https://github.com/vitessio/vitess/pull/15395) + * VReplication: Remove auto_increment clauses for MoveTables to a sharded keyspace [#15679](https://github.com/vitessio/vitess/pull/15679) + * VReplication: Move ENUM and SET mappings from vplayer to vstreamer [#15723](https://github.com/vitessio/vitess/pull/15723) + * VReplication: Add stream DDL processing stats [#15769](https://github.com/vitessio/vitess/pull/15769) + * Improve WaitForPos errors, don't include Result struct in message [#15962](https://github.com/vitessio/vitess/pull/15962) +#### VTCombo + * [vtcombo] Expose `--tablet_types_to_wait` flag [#14951](https://github.com/vitessio/vitess/pull/14951) +#### VTGate + * Add sql text counts stats to `vtcombo`,`vtgate`+`vttablet` [#15897](https://github.com/vitessio/vitess/pull/15897) + * `vtgate`: support filtering tablets by tablet-tags [#15911](https://github.com/vitessio/vitess/pull/15911) + * Add support for sampling rate in `streamlog` [#15919](https://github.com/vitessio/vitess/pull/15919) +#### VTorc + * Improve VTOrc startup flow [#15315](https://github.com/vitessio/vitess/pull/15315) + * Add api end point to print the current database state in VTOrc [#15485](https://github.com/vitessio/vitess/pull/15485) + * Make `Durabler` interface methods public [#15548](https://github.com/vitessio/vitess/pull/15548) + * VTOrc: Rework recovery registration [#15591](https://github.com/vitessio/vitess/pull/15591) +#### vtctldclient + * `proto`: lexical ordering of `ExecuteMultiFetchAsDBA` [#15558](https://github.com/vitessio/vitess/pull/15558) +#### vttestserver + * Add initialize-with-vt-dba-tcp flag to enable TCP/IP connection access to the underlying MySQL instance [#15354](https://github.com/vitessio/vitess/pull/15354) +### Feature Request +#### Build/CI + * CI workflows: Split long running vreplication workflows [#15834](https://github.com/vitessio/vitess/pull/15834) +#### Cluster management + * [vtctldclient] Add GetShardReplication [#15389](https://github.com/vitessio/vitess/pull/15389) +#### Query Serving + * Update with Limit Plan [#15107](https://github.com/vitessio/vitess/pull/15107) + * Add support for Update Multi Table [#15211](https://github.com/vitessio/vitess/pull/15211) + * Delete with subquery support [#15219](https://github.com/vitessio/vitess/pull/15219) + * Multi Target Delete Support [#15294](https://github.com/vitessio/vitess/pull/15294) + * Feature: Multi Target Update Support [#15402](https://github.com/vitessio/vitess/pull/15402) + * Foreign Key: Add support for multi target delete [#15504](https://github.com/vitessio/vitess/pull/15504) + * Foreign Key: Add support for Multi Table and Multi Target Update Statement [#15523](https://github.com/vitessio/vitess/pull/15523) + * Respect Straight Join in Vitess query planning [#15528](https://github.com/vitessio/vitess/pull/15528) + * feat: Add support for Insert with row alias [#15790](https://github.com/vitessio/vitess/pull/15790) + * Add support for multi table update with non literal value [#15980](https://github.com/vitessio/vitess/pull/15980) +#### Throttler + * Tablet throttler: adding more stats [#15224](https://github.com/vitessio/vitess/pull/15224) +#### VReplication + * Experimental: Multi-tenant import support in Vitess [#15503](https://github.com/vitessio/vitess/pull/15503) + * VDiff/OnlineDDL: add support for running VDiffs for OnlineDDL migrations [#15546](https://github.com/vitessio/vitess/pull/15546) + * Multi-tenant MoveTables: Create vreplication streams only on specified shards [#15746](https://github.com/vitessio/vitess/pull/15746) + * Multi-tenant MoveTables: allow switching replica/rdonly traffic separately before switching primary traffic [#15768](https://github.com/vitessio/vitess/pull/15768) + * Multi-tenant migrations: add topo locking while updating keyspace routing rules [#15807](https://github.com/vitessio/vitess/pull/15807) +#### VTorc + * VTOrc optimize TMC usage [#15356](https://github.com/vitessio/vitess/pull/15356) + * VTOrc checks and fixes replication misconfiguration issues [#15881](https://github.com/vitessio/vitess/pull/15881) +### Internal Cleanup +#### Backup and Restore + * endtoend: Remove usage of deprecated terminology [#15827](https://github.com/vitessio/vitess/pull/15827) +#### Build/CI + * [e2e] More vtctldclient updates in tests [#15276](https://github.com/vitessio/vitess/pull/15276) + * wranger: Clean up leak check and use existing version [#15334](https://github.com/vitessio/vitess/pull/15334) + * update andrew's email [#15495](https://github.com/vitessio/vitess/pull/15495) + * Remove self-hosted runners in ci_workflow_gen [#15989](https://github.com/vitessio/vitess/pull/15989) + * Linkname removal (step 1) [#16016](https://github.com/vitessio/vitess/pull/16016) +#### Cluster management + * go/vt/wrangler: pass reparent options structs [#15251](https://github.com/vitessio/vitess/pull/15251) + * delete TestActionAndTimeout [#15322](https://github.com/vitessio/vitess/pull/15322) + * Deprecate old reparent metrics and replace with new ones [#16031](https://github.com/vitessio/vitess/pull/16031) +#### Docker + * Revert the removal of the MySQL binaries in the `vitess/lite` image [#16042](https://github.com/vitessio/vitess/pull/16042) +#### Examples + * Update env.sh so that is does not error when running on Mac [#15835](https://github.com/vitessio/vitess/pull/15835) + * Local Examples: Add --binary-as-hex=false flag to mysql alias [#15996](https://github.com/vitessio/vitess/pull/15996) +#### General + * New for loops and some assert/require [#15194](https://github.com/vitessio/vitess/pull/15194) + * Remove loopclosure captures from tests [#15202](https://github.com/vitessio/vitess/pull/15202) + * Make `--pprof-http` default to false [#15260](https://github.com/vitessio/vitess/pull/15260) + * discovery: Remove unused code [#15332](https://github.com/vitessio/vitess/pull/15332) + * chore: remove repetitive words [#15449](https://github.com/vitessio/vitess/pull/15449) + * Migrate to math/rand/v2 [#15513](https://github.com/vitessio/vitess/pull/15513) + * Fix misorganized annotations [#15566](https://github.com/vitessio/vitess/pull/15566) + * changelogs: squash 19.0.2/19.0.3 into just 19.0.3 and remove 19.0.2 [#15665](https://github.com/vitessio/vitess/pull/15665) + * Cleanup usage of FLUSH PRIVILEGES [#15700](https://github.com/vitessio/vitess/pull/15700) + * Upgrade the Golang Dependencies [#15743](https://github.com/vitessio/vitess/pull/15743) + * grpc: Always pass through context for dialer [#15781](https://github.com/vitessio/vitess/pull/15781) + * Switch to use semisync source / replica plugins [#15791](https://github.com/vitessio/vitess/pull/15791) + * Use replica queries when available [#15808](https://github.com/vitessio/vitess/pull/15808) +#### Messaging + * messager: add consistent log prefix w/ table name [#15973](https://github.com/vitessio/vitess/pull/15973) +#### Observability + * Upgrade the golang version used `vitess-mixin` [#15972](https://github.com/vitessio/vitess/pull/15972) +#### Online DDL + * New unified internal table names format: part 2, generating new names [#15178](https://github.com/vitessio/vitess/pull/15178) +#### Query Serving + * Make tablet collation mismatch warning throttled [#15123](https://github.com/vitessio/vitess/pull/15123) + * schemadiff: Clean up MySQL version from diff hints [#15210](https://github.com/vitessio/vitess/pull/15210) + * refactor: change FuncExpr to use Exprs instead of SelectExprs [#15368](https://github.com/vitessio/vitess/pull/15368) + * refactor: clean up semantics package [#15385](https://github.com/vitessio/vitess/pull/15385) + * planbuilder: Cleanup unused logic [#15415](https://github.com/vitessio/vitess/pull/15415) + * cleanup: make sure we use the right Offset [#15576](https://github.com/vitessio/vitess/pull/15576) + * Add more fields to the marshal output of column [#15622](https://github.com/vitessio/vitess/pull/15622) + * modify error message when transaction not found in numbered pool [#15760](https://github.com/vitessio/vitess/pull/15760) + * Delete the deprecated pool size flags [#15844](https://github.com/vitessio/vitess/pull/15844) + * refactor: introduce helper method to extract logic [#15939](https://github.com/vitessio/vitess/pull/15939) + * refactor: remove logical plan interface [#16006](https://github.com/vitessio/vitess/pull/16006) + * Decouple topotools from vschema [#16008](https://github.com/vitessio/vitess/pull/16008) +#### TabletManager + * srvtopo: Setup metrics in init() function [#15304](https://github.com/vitessio/vitess/pull/15304) + * Revert "Skip for-loop alloc in `go/vt/discovery/healthcheck.go`" [#15328](https://github.com/vitessio/vitess/pull/15328) + * mysqlctld: Remove unneeded resets in init_db.sql [#15832](https://github.com/vitessio/vitess/pull/15832) + * mysql: Handle more deprecated SQL commands [#15907](https://github.com/vitessio/vitess/pull/15907) +#### Throttler + * Throttler: refactor stats variables [#15574](https://github.com/vitessio/vitess/pull/15574) + * Tablet throttler: remove `LowPriority` logic [#16013](https://github.com/vitessio/vitess/pull/16013) +#### Topology + * topo: Clean up unused code [#15515](https://github.com/vitessio/vitess/pull/15515) + * Etcd2Topo: Use node's ModRevision consistently for in-memory topo.Version value [#15847](https://github.com/vitessio/vitess/pull/15847) + * Fix documentation for `--lock-timeout` [#16021](https://github.com/vitessio/vitess/pull/16021) +#### VReplication + * Remove Usage of VReplicationExec For _vt.vreplication Reads [#14424](https://github.com/vitessio/vitess/pull/14424) + * VReplication: improve reliability of log management [#15374](https://github.com/vitessio/vitess/pull/15374) + * delete unused code in vreplication e2e tests [#15378](https://github.com/vitessio/vitess/pull/15378) + * MoveTables: remove option to specify source keyspace alias for multi-tenant migrations [#15712](https://github.com/vitessio/vitess/pull/15712) + * Delete the deprecated vreplication tablet type flag [#15857](https://github.com/vitessio/vitess/pull/15857) + * VReplication: Remove noisy logs [#15987](https://github.com/vitessio/vitess/pull/15987) + * VReplication: refactor denied tables unit test, add couple more tests [#15995](https://github.com/vitessio/vitess/pull/15995) +#### VTAdmin + * Update Node version to current LTS release [#15822](https://github.com/vitessio/vitess/pull/15822) +#### VTTablet + * go/cmd: Audit and fix context.Background() usage [#15928](https://github.com/vitessio/vitess/pull/15928) +#### VTorc + * Remove unneeded loading of the MySQL driver [#15502](https://github.com/vitessio/vitess/pull/15502) + * vtorc: Cleanup unused code [#15508](https://github.com/vitessio/vitess/pull/15508) + * Remove reading emergently instances [#15580](https://github.com/vitessio/vitess/pull/15580) + * Cleanup unused vtorc code [#15595](https://github.com/vitessio/vitess/pull/15595) + * VTOrc: Cleanup node registration and unused code [#15617](https://github.com/vitessio/vitess/pull/15617) + * Remove unused code in VTOrc [#15813](https://github.com/vitessio/vitess/pull/15813) + * vtorc: Switch to Vitess stats [#15948](https://github.com/vitessio/vitess/pull/15948) + * Deprecate old metrics in VTOrc and replace with new ones [#15994](https://github.com/vitessio/vitess/pull/15994) +#### vtctl + * Remove legacy `EmergencyReparentShard` stats [#15941](https://github.com/vitessio/vitess/pull/15941) +### Other +#### Other + * Match MySQL's `LAST_INSERT_ID` behaviour [#15697](https://github.com/vitessio/vitess/pull/15697) +### Performance +#### General + * prevent vtctld from creating tons of S3 connections [#15296](https://github.com/vitessio/vitess/pull/15296) +#### Query Serving + * Skip for-loop alloc in `go/vt/discovery/healthcheck.go` [#15326](https://github.com/vitessio/vitess/pull/15326) + * logstats: do not allocate memory while logging [#15539](https://github.com/vitessio/vitess/pull/15539) + * rewrite shuffleTablets to be clearer and more efficient [#15716](https://github.com/vitessio/vitess/pull/15716) +#### TabletManager + * Fix: transition to `math/rand/v2` for Improved Performance and Code Clarity [#15438](https://github.com/vitessio/vitess/pull/15438) +#### VReplication + * VReplication Workflows (RowStreamer): explicitly set read only when creating snapshots in the copy phase [#15690](https://github.com/vitessio/vitess/pull/15690) +#### VTTablet + * Improve performance for `BaseShowTablesWithSizes` query. [#15713](https://github.com/vitessio/vitess/pull/15713) + * Do not load table stats when booting `vttablet`. [#15715](https://github.com/vitessio/vitess/pull/15715) + * [release-20.0] Do not load table stats when booting `vttablet`. (#15715) [#16101](https://github.com/vitessio/vitess/pull/16101) +### Regression +#### Query Serving + * Fix routing rule query rewrite [#15253](https://github.com/vitessio/vitess/pull/15253) + * fix: remove keyspace from column during query builder [#15514](https://github.com/vitessio/vitess/pull/15514) + * Fix regression where inserts into reference tables with a different name on sharded keyspaces were not routed correctly. [#15796](https://github.com/vitessio/vitess/pull/15796) + * fix: derived table join column expression to be part of add join predicate on rewrite [#15956](https://github.com/vitessio/vitess/pull/15956) + * fix: insert on duplicate update to add list argument in the bind variables map [#15961](https://github.com/vitessio/vitess/pull/15961) + * [release-20.0-rc] fix: order by subquery planning (#16049) [#16133](https://github.com/vitessio/vitess/pull/16133) + * [release-20.0] fix: order by subquery planning (#16049) [#16134](https://github.com/vitessio/vitess/pull/16134) +#### Throttler + * Enable 'heartbeat_on_demand_duration' in local/examples [#15204](https://github.com/vitessio/vitess/pull/15204) +#### vttestserver + * Fix logging issue when running in Docker with the syslog daemon disabled [#15176](https://github.com/vitessio/vitess/pull/15176) +### Release +#### General + * Bump to `v20.0.0-SNAPSHOT` after the `v19.0.0-RC1` release [#15138](https://github.com/vitessio/vitess/pull/15138) + * Copy `v19.0.0-RC1` release notes on `main` [#15164](https://github.com/vitessio/vitess/pull/15164) + * Copy `v19.0.0` release notes on `main` [#15417](https://github.com/vitessio/vitess/pull/15417) + * Copy `v17.0.6` release notes on `main` [#15486](https://github.com/vitessio/vitess/pull/15486) + * Copy `v18.0.3` release notes on `main` [#15488](https://github.com/vitessio/vitess/pull/15488) + * Copy `v19.0.1` release notes on `main` [#15490](https://github.com/vitessio/vitess/pull/15490) + * Copy `v19.0.2` release notes on `main` [#15647](https://github.com/vitessio/vitess/pull/15647) + * Copy `v18.0.4` release notes on `main` [#15659](https://github.com/vitessio/vitess/pull/15659) + * Copy `v19.0.3` release notes on `main` [#15661](https://github.com/vitessio/vitess/pull/15661) + * Copy `v18.0.5` release notes on `main` [#15886](https://github.com/vitessio/vitess/pull/15886) + * Copy `v19.0.4` release notes on `main` [#15887](https://github.com/vitessio/vitess/pull/15887) + * Copy `v17.0.7` release notes on `main` [#15890](https://github.com/vitessio/vitess/pull/15890) + * [release-20.0-rc] Code Freeze for `v20.0.0-RC1` [#16046](https://github.com/vitessio/vitess/pull/16046) + * Bump to `v21.0.0-SNAPSHOT` after the `v20.0.0-RC1` release [#16047](https://github.com/vitessio/vitess/pull/16047) +### Testing +#### Build/CI + * Rewrite _many_ tests to use vtctldclient invocations, mostly non-output related stuff [#15270](https://github.com/vitessio/vitess/pull/15270) + * [e2e] vtctld init tablet and some output-based commands [#15297](https://github.com/vitessio/vitess/pull/15297) + * CI: Address data races on memorytopo Conn.closed [#15365](https://github.com/vitessio/vitess/pull/15365) + * Reduce excessing logging in CI [#15462](https://github.com/vitessio/vitess/pull/15462) + * Split unit test and unit race into 2 components [#15734](https://github.com/vitessio/vitess/pull/15734) + * CI: Address data race in TestSchemaVersioning [#15998](https://github.com/vitessio/vitess/pull/15998) +#### CLI + * Add required tests for `internal/flag` [#15220](https://github.com/vitessio/vitess/pull/15220) + * test: Add missing tests and refactor existing tests for `go/flagutil` [#15789](https://github.com/vitessio/vitess/pull/15789) +#### Cluster management + * Fix Data race in tests introduced in #15934 [#15993](https://github.com/vitessio/vitess/pull/15993) +#### General + * Added unit tests for cmd/internal/docgen package [#15019](https://github.com/vitessio/vitess/pull/15019) + * unit test for go/yaml2/yaml.go [#15027](https://github.com/vitessio/vitess/pull/15027) + * Added unit tests for `go/cmd/rulesctl/` package [#15028](https://github.com/vitessio/vitess/pull/15028) + * Added tests for the go/trace package [#15052](https://github.com/vitessio/vitess/pull/15052) + * Added missing tests for the go/streamlog package [#15064](https://github.com/vitessio/vitess/pull/15064) + * Added unit tests for vt/grpcclient package [#15072](https://github.com/vitessio/vitess/pull/15072) + * modernize various tests [#15184](https://github.com/vitessio/vitess/pull/15184) + * go1.22: remove outdated loopclosure captures in tests [#15227](https://github.com/vitessio/vitess/pull/15227) + * chore: modernize tests [#15244](https://github.com/vitessio/vitess/pull/15244) + * Add required tests for `go/netutil` [#15392](https://github.com/vitessio/vitess/pull/15392) + * Add required tests for `go/stats/opentsdb` [#15394](https://github.com/vitessio/vitess/pull/15394) + * test: Replace `t.fatalf` with testify `require` in `go/vt/schemamanager` [#15600](https://github.com/vitessio/vitess/pull/15600) + * Remove mysql 5.7 tests that are no longer required [#15809](https://github.com/vitessio/vitess/pull/15809) + * Fix unit-test-runner bug [#15815](https://github.com/vitessio/vitess/pull/15815) + * test: Add tests for `go/ioutil` and refactor existing [#15885](https://github.com/vitessio/vitess/pull/15885) + * test: Add required tests for `vt/key`, `timer` and `cache/theine/bf` [#15976](https://github.com/vitessio/vitess/pull/15976) +#### Observability + * VStreamer: add throttled logs when row/result/vstreamers get throttled. [#14936](https://github.com/vitessio/vitess/pull/14936) +#### Query Serving + * test: skip should mark the correct *testing.T [#15333](https://github.com/vitessio/vitess/pull/15333) + * test: Add required tests for `go/mysql/collations/charset` [#15435](https://github.com/vitessio/vitess/pull/15435) + * test: Add missing tests for `go/mysql/datetime` [#15501](https://github.com/vitessio/vitess/pull/15501) + * schemadiff: add `EntityDiffByStatement`, a testing friendly utility [#15519](https://github.com/vitessio/vitess/pull/15519) + * `schemadiff`: better nil check validation [#15526](https://github.com/vitessio/vitess/pull/15526) + * Add testing for shard scoped foreign keys [#15571](https://github.com/vitessio/vitess/pull/15571) + * chore: use interface instead of struct for tests [#15581](https://github.com/vitessio/vitess/pull/15581) + * Fix AVG() sharded planning [#15626](https://github.com/vitessio/vitess/pull/15626) + * Run launchable in unit race [#15686](https://github.com/vitessio/vitess/pull/15686) + * Make upgrade downgrade tests faster by removing redundancy [#15687](https://github.com/vitessio/vitess/pull/15687) + * Fix Foreign key fuzzer to ignore rows affected [#15841](https://github.com/vitessio/vitess/pull/15841) + * `schemadiff`: adding charset/collation tests [#15872](https://github.com/vitessio/vitess/pull/15872) + * test: Add required tests for `go/logstats` [#15893](https://github.com/vitessio/vitess/pull/15893) + * test: Add missing/required tests for `sqltypes` and `mathstats` [#15920](https://github.com/vitessio/vitess/pull/15920) + * test: Cleaner plan tests output [#15922](https://github.com/vitessio/vitess/pull/15922) +#### TabletManager + * test: Add missing tests for `go/vt/mysqlctl` [#15585](https://github.com/vitessio/vitess/pull/15585) + * test: Add e2e tests for `replication` [#15671](https://github.com/vitessio/vitess/pull/15671) +#### Throttler + * test: Use testify require/assert instead of t.Fatal/Error in `go/vt/throttler` [#15703](https://github.com/vitessio/vitess/pull/15703) + * v20 backport: CI upgrade/downgrade tests for Online DDL / throttler / vreplication flow [#16065](https://github.com/vitessio/vitess/pull/16065) + * [release-20.0-rc] v20 backport: CI upgrade/downgrade tests for Online DDL / throttler / vreplication flow (#16065) [#16082](https://github.com/vitessio/vitess/pull/16082) +#### VReplication + * VStreamer Unit Tests: framework to remove the need to specify serialized strings in row events for unit tests [#14903](https://github.com/vitessio/vitess/pull/14903) + * VtctldClient Reshard: add e2e tests to confirm CLI options and fix discovered issues. [#15353](https://github.com/vitessio/vitess/pull/15353) + * VStreamer unit test: port remaining tests to new framework [#15366](https://github.com/vitessio/vitess/pull/15366) + * VReplication: Fix vtctldclient SwitchReads related bugs and move the TestBasicV2Workflows e2e test to vtctldclient [#15579](https://github.com/vitessio/vitess/pull/15579) + * VStreamer unit tests: refactor pending test [#15845](https://github.com/vitessio/vitess/pull/15845) +#### VTorc + * Add missing tests for `go/vt/vtorc/collection` [#15070](https://github.com/vitessio/vitess/pull/15070) +#### vtctldclient + * Add tests for GetTablets partial results [#15829](https://github.com/vitessio/vitess/pull/15829) +#### vttestserver + * Add `no_scatter` flag to vttestserver [#15670](https://github.com/vitessio/vitess/pull/15670) + diff --git a/changelog/20.0/20.0.0/release_notes.md b/changelog/20.0/20.0.0/release_notes.md new file mode 100644 index 00000000000..ffcf8057a15 --- /dev/null +++ b/changelog/20.0/20.0.0/release_notes.md @@ -0,0 +1,369 @@ +# Release of Vitess v20.0.0 + +## Summary + +### Table of Contents + +- **[Major Changes](#major-changes)** + - **[Deletions](#deletions)** + - [`--vreplication_tablet_type` flag](#vreplication-tablet-type-deletion) + - [Pool Capacity Flags](#pool-flags-deletion) + - [vitess/base and vitess/k8s Docker images](#base-k8s-images) + - [`gh-ost` binary and endtoend tests](#gh-ost-binary-tests-removal) + - [Legacy `EmergencyReparentShard` stats](#legacy-emergencyshardreparent-stats) + - **[Breaking changes](#breaking-changes)** + - [Metric Name Changes in VTOrc](#metric-change-vtorc) + - [ENUM and SET column handling in VTGate VStream API](#enum-set-vstream) + - [`shutdown_grace_period` Default Change](#shutdown-grace-period-default) + - [New `unmanaged` Flag and `disable_active_reparents` deprecation](#unmanaged-flag) + - [`recovery-period-block-duration` Flag deprecation](#recovery-block-deprecation) + - [`mysqlctld` `onterm-timeout` Default Change](#mysqlctld-onterm-timeout) + - [`MoveTables` now removes `auto_increment` clauses by default when moving tables from an unsharded keyspace to a sharded one](#move-tables-auto-increment) + - [`Durabler` interface method renaming](#durabler-interface-method-renaming) + - **[Query Compatibility](#query-compatibility)** + - [Vindex Hints](#vindex-hints) + - [Update with Limit Support](#update-limit) + - [Update with Multi Table Support](#multi-table-update) + - [Update with Multi Target Support](#update-multi-target) + - [Delete with Subquery Support](#delete-subquery) + - [Delete with Multi Target Support](#delete-multi-target) + - [User Defined Functions Support](#udf-support) + - [Insert Row Alias Support](#insert-row-alias-support) + - **[Query Timeout](#query-timeout)** + - **[Flag changes](#flag-changes)** + - [`pprof-http` default change](#pprof-http-default) + - [New `healthcheck-dial-concurrency` flag](#healthcheck-dial-concurrency-flag) + - [New minimum for `--buffer_min_time_between_failovers`](#buffer_min_time_between_failovers-flag) + - [New `track-udfs` vtgate flag](#vtgate-track-udfs-flag) + - [Help text fix for `--lock-timeout`](#documentation-lock-timeout) + - [New `--querylog-sample-rate` flag](#querylog-sample-rate-flag) + - [New `--tablet-filter-tags` flag](#tablet-filter-tags-flag) + +- **[Minor Changes](#minor-changes)** + - **[New Stats](#new-stats)** + - [VTTablet Query Cache Hits and Misses](#vttablet-query-cache-hits-and-misses) + - [VTGate and VTTablet Query Text Characters Processed](#vttablet-query-text-characters-processed) + - **[`SIGHUP` reload of gRPC client static auth creds](#sighup-reload-of-grpc-client-auth-creds)** + - **[VTAdmin](#vtadmin)** + - [Updated to node v20.12.2](#updated-node) + - [Replaced highcharts with d3](#replaced-highcharts) + +## Major Changes + +### Deletion + +#### `--vreplication_tablet_type` flag + +The previously deprecated flag `--vreplication_tablet_type` has been deleted. + +#### Pool Capacity Flags + +The previously deprecated flags `--queryserver-config-query-pool-waiter-cap`, `--queryserver-config-stream-pool-waiter-cap` and `--queryserver-config-txpool-waiter-cap` have been deleted. + +#### `vitess/base` and `vitess/k8s` Docker images + +Since we have deleted MySQL from our `vitess/lite` image, we are removing the `vitess/base` and `vitess/k8s` images. + +These images are no longer useful since we can use `vitess/lite` as the base of many other Docker images (`vitess/vtgate`, `vitess/vtgate`, ...). + +#### `gh-ost` binary and endtoend tests + +Vitess 20.0 drops support for `gh-ost` DDL strategy. + +`vttablet` binary no longer embeds a `gh-ost` binary. Users of `gh-ost` DDL strategy will need to supply a `gh-ost` binary on the `vttablet` host or pod. Vitess will look for the `gh-ost` binary in the system `PATH`; otherwise the user should supply `vttablet --gh-ost-path`. + +Vitess' endtoend tests no longer use nor test `gh-ost` migrations. + +#### Legacy `EmergencyReparentShard` stats + +The following `EmergencyReparentShard` stats were deprecated in Vitess 18.0 and are removed in Vitess 20.0: +- `ers_counter` +- `ers_success_counter` +- `ers_failure_counter` + +These counters are replaced by the following stats _(introduced in Vitess 18.0)_: +- `emergency_reparent_counts` - Number of times `EmergencyReparentShard` has been run. It is further subdivided by the keyspace, shard and the result of the operation. +- `planned_reparent_counts` - Number of times `PlannedReparentShard` has been run. It is further subdivided by the keyspace, shard and the result of the operation. + +Also, the `reparent_shard_operation_timings` stat was added to provide per-operation timings of reparent operations. + +### Breaking Changes + +#### Metric Name Changes in VTOrc + +The following metric names have been changed in VTOrc. The old metrics are still available in `/debug/vars` for this release, but will be removed in later releases. The new metric names and the deprecated metric names resolve to the same metric name on prometheus, so there is no change there. + +| Old Metric Name | New Metric Name | Name in Prometheus | +|:--------------------------------------------:|:----------------------------------------:|:--------------------------------------------------:| +| `analysis.change.write` | `AnalysisChangeWrite` | `vtorc_analysis_change_write` | +| `audit.write` | `AuditWrite` | `vtorc_audit_write` | +| `discoveries.attempt` | `DiscoveriesAttempt` | `vtorc_discoveries_attempt` | +| `discoveries.fail` | `DiscoveriesFail` | `vtorc_discoveries_fail` | +| `discoveries.instance_poll_seconds_exceeded` | `DiscoveriesInstancePollSecondsExceeded` | `vtorc_discoveries_instance_poll_seconds_exceeded` | +| `discoveries.queue_length` | `DiscoveriesQueueLength` | `vtorc_discoveries_queue_length` | +| `discoveries.recent_count` | `DiscoveriesRecentCount` | `vtorc_discoveries_recent_count` | +| `instance.read` | `InstanceRead` | `vtorc_instance_read` | +| `instance.read_topology` | `InstanceReadTopology` | `vtorc_instance_read_topology` | +| `emergency_reparent_counts` | `EmergencyReparentCounts` | `vtorc_emergency_reparent_counts` | +| `planned_reparent_counts` | `PlannedReparentCounts` | `vtorc_planned_reparent_counts` | +| `reparent_shard_operation_timings` | `ReparentShardOperationTimings` | `vtorc_reparent_shard_operation_timings_bucket` | + + + +#### ENUM and SET column handling in VTGate VStream API + +The [VTGate VStream API](https://vitess.io/docs/reference/vreplication/vstream/) now returns [`ENUM`](https://dev.mysql.com/doc/refman/en/enum.html) and [`SET`](https://dev.mysql.com/doc/refman/en/set.html) column type values in [`VEvent`](https://pkg.go.dev/vitess.io/vitess/go/vt/proto/binlogdata#VEvent) messages (in the embedded [`RowChange`](https://pkg.go.dev/vitess.io/vitess/go/vt/proto/binlogdata#RowChange) messages) as their string values instead of the integer based ones — in both the copy/snapshot phase and the streaming phase. This change was done to make the `VStream` API more user-friendly, intuitive, and to align the behavior across both phases. Before [this change](https://github.com/vitessio/vitess/pull/15723) the values for [`ENUM`](https://dev.mysql.com/doc/refman/en/enum.html) and [`SET`](https://dev.mysql.com/doc/refman/en/set.html) columns were string values in the copy phase but integer values (which only have an internal meaning to MySQL) in the streaming phase. This inconsistency led to various [challenges and issues](https://github.com/vitessio/vitess/issues/15750) for each `VStream` client/consumer (e.g. the [`Debezium` Vitess connector](https://debezium.io/documentation/reference/stable/connectors/vitess.html) failed to properly perform a snapshot for tables containing these column types). Now the behavior is intuitive — clients need the string values as the eventual sink is often not MySQL so each consumer needed to perform the mappings themselves — and consistent. While this is a (potentially) breaking change, a new boolean field has been added to the [`FieldEvent`](https://pkg.go.dev/vitess.io/vitess/go/vt/proto/binlogdata#FieldEvent) message called `EnumSetStringValues`. When that field is `false` (in Vitess v19 and older) then the consumer will need to perform the mappings during streaming phase, but not during copy phase. When this field is `true`, then no mapping is required. This will help to ensure a smooth transition for all consumers over time. To demonstrate, let's look at the textual output (printing the received `VEvents` as strings) when streaming a single `enum_set_test` table from the unsharded `commerce` keyspace so that we can see what the VStream looks like before and after when we start a new VStream in copy/snapshot mode and then transition to streaming mode for the following table: + +```sql +CREATE TABLE `enum_set_test` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(120) DEFAULT NULL, + `shirt_size` enum('small','medium','large','xlarge','xxlarge') DEFAULT NULL, + `hobbies` set('knitting','cooking','pickleball','biking','hiking','motorcycle','video games','reading') DEFAULT NULL, + PRIMARY KEY (`id`) +) +``` + +And with the table having this data when we start our `VStream` and begin the copy/snapshot phase: + +```sql +mysql> select * from enum_set_test; ++----+-----------+------------+-------------------------+ +| id | name | shirt_size | hobbies | ++----+-----------+------------+-------------------------+ +| 1 | Billy Bob | xlarge | cooking,reading | +| 2 | Sally Mae | medium | knitting,cooking,hiking | ++----+-----------+------------+-------------------------+ +2 rows in set (0.00 sec) +``` + +And finally we will perform the following inserts and updates to the table during the streaming phase: + +```sql +insert into enum_set_test values (3, "Matt Lord", 'medium', 'pickleball,biking,hiking,motorcycle,video games,reading'); +insert into enum_set_test values (4, "Jerry Badyellow", 'large', ''); +update enum_set_test set shirt_size = 'small', hobbies = 'knitting,cooking,hiking,reading' where id = 2; +``` + +Vitess v19 and older: + +```text +[type:BEGIN keyspace:"commerce" shard:"0" type:FIELD field_event:{table_name:"commerce.enum_set_test" fields:{name:"id" type:INT32 table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"id" column_length:11 charset:63 flags:49667 column_type:"int"} fields:{name:"name" type:VARCHAR table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"name" column_length:480 charset:255 column_type:"varchar(120)"} fields:{name:"shirt_size" type:ENUM table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"shirt_size" column_length:28 charset:255 flags:256 column_type:"enum('small','medium','large','xlarge','xxlarge')"} fields:{name:"hobbies" type:SET table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"hobbies" column_length:288 charset:255 flags:2048 column_type:"set('knitting','cooking','pickleball','biking','hiking','motorcycle','video games','reading')"} keyspace:"commerce" shard:"0"} keyspace:"commerce" shard:"0"] +[type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/ce357206-0d49-11ef-8fd1-a74564279579:1-35"}} keyspace:"commerce" shard:"0"] +[type:ROW row_event:{table_name:"commerce.enum_set_test" row_changes:{after:{lengths:1 lengths:9 lengths:6 lengths:15 values:"1Billy Bobxlargecooking,reading"}} keyspace:"commerce" shard:"0"} keyspace:"commerce" shard:"0" type:ROW row_event:{table_name:"commerce.enum_set_test" row_changes:{after:{lengths:1 lengths:9 lengths:6 lengths:23 values:"2Sally Maemediumknitting,cooking,hiking"}} keyspace:"commerce" shard:"0"} keyspace:"commerce" shard:"0" type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/ce357206-0d49-11ef-8fd1-a74564279579:1-35" table_p_ks:{table_name:"enum_set_test" lastpk:{fields:{name:"id" type:INT32 charset:63 flags:49667} rows:{lengths:1 values:"2"}}}}} keyspace:"commerce" shard:"0" type:COMMIT keyspace:"commerce" shard:"0"] +[type:BEGIN keyspace:"commerce" shard:"0" type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/ce357206-0d49-11ef-8fd1-a74564279579:1-35"}} keyspace:"commerce" shard:"0" type:COMMIT keyspace:"commerce" shard:"0"] +[type:COPY_COMPLETED keyspace:"commerce" shard:"0" type:COPY_COMPLETED] +[type:BEGIN timestamp:1715179728 current_time:1715179728532658000 keyspace:"commerce" shard:"0" type:FIELD timestamp:1715179728 field_event:{table_name:"commerce.enum_set_test" fields:{name:"id" type:INT32 table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"id" column_length:11 charset:63 flags:49667 column_type:"int"} fields:{name:"name" type:VARCHAR table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"name" column_length:480 charset:255 column_type:"varchar(120)"} fields:{name:"shirt_size" type:ENUM table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"shirt_size" column_length:28 charset:255 flags:256 column_type:"enum('small','medium','large','xlarge','xxlarge')"} fields:{name:"hobbies" type:SET table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"hobbies" column_length:288 charset:255 flags:2048 column_type:"set('knitting','cooking','pickleball','biking','hiking','motorcycle','video games','reading')"} keyspace:"commerce" shard:"0"} current_time:1715179728535652000 keyspace:"commerce" shard:"0" type:ROW timestamp:1715179728 row_event:{table_name:"commerce.enum_set_test" row_changes:{after:{lengths:1 lengths:9 lengths:1 lengths:3 values:"3Matt Lord2252"}} keyspace:"commerce" shard:"0" flags:1} current_time:1715179728535739000 keyspace:"commerce" shard:"0" type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/ce357206-0d49-11ef-8fd1-a74564279579:1-36"}} keyspace:"commerce" shard:"0" type:COMMIT timestamp:1715179728 current_time:1715179728535754000 keyspace:"commerce" shard:"0"] +[type:BEGIN timestamp:1715179735 current_time:1715179735538607000 keyspace:"commerce" shard:"0" type:ROW timestamp:1715179735 row_event:{table_name:"commerce.enum_set_test" row_changes:{after:{lengths:1 lengths:15 lengths:1 lengths:1 values:"4Jerry Badyellow30"}} keyspace:"commerce" shard:"0" flags:1} current_time:1715179735538659000 keyspace:"commerce" shard:"0" type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/ce357206-0d49-11ef-8fd1-a74564279579:1-37"}} keyspace:"commerce" shard:"0" type:COMMIT timestamp:1715179735 current_time:1715179735538672000 keyspace:"commerce" shard:"0"] +[type:BEGIN timestamp:1715179741 current_time:1715179741728690000 keyspace:"commerce" shard:"0" type:ROW timestamp:1715179741 row_event:{table_name:"commerce.enum_set_test" row_changes:{before:{lengths:1 lengths:9 lengths:1 lengths:2 values:"2Sally Mae219"} after:{lengths:1 lengths:9 lengths:1 lengths:3 values:"2Sally Mae1147"}} keyspace:"commerce" shard:"0" flags:1} current_time:1715179741728730000 keyspace:"commerce" shard:"0" type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/ce357206-0d49-11ef-8fd1-a74564279579:1-38"}} keyspace:"commerce" shard:"0" type:COMMIT timestamp:1715179741 current_time:1715179741728744000 keyspace:"commerce" shard:"0"] +``` + +Vitess v20 and newer: + +```text +[type:BEGIN keyspace:"commerce" shard:"0" type:FIELD field_event:{table_name:"commerce.enum_set_test" fields:{name:"id" type:INT32 table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"id" column_length:11 charset:63 flags:49667 column_type:"int"} fields:{name:"name" type:VARCHAR table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"name" column_length:480 charset:255 column_type:"varchar(120)"} fields:{name:"shirt_size" type:ENUM table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"shirt_size" column_length:28 charset:255 flags:256 column_type:"enum('small','medium','large','xlarge','xxlarge')"} fields:{name:"hobbies" type:SET table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"hobbies" column_length:288 charset:255 flags:2048 column_type:"set('knitting','cooking','pickleball','biking','hiking','motorcycle','video games','reading')"} keyspace:"commerce" shard:"0" enum_set_string_values:true} keyspace:"commerce" shard:"0"] +[type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/156f702a-0d47-11ef-8723-653d045ab990:1-50"}} keyspace:"commerce" shard:"0"] +[type:ROW row_event:{table_name:"commerce.enum_set_test" row_changes:{after:{lengths:1 lengths:9 lengths:6 lengths:15 values:"1Billy Bobxlargecooking,reading"}} keyspace:"commerce" shard:"0"} keyspace:"commerce" shard:"0" type:ROW row_event:{table_name:"commerce.enum_set_test" row_changes:{after:{lengths:1 lengths:9 lengths:6 lengths:23 values:"2Sally Maemediumknitting,cooking,hiking"}} keyspace:"commerce" shard:"0"} keyspace:"commerce" shard:"0" type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/156f702a-0d47-11ef-8723-653d045ab990:1-50" table_p_ks:{table_name:"enum_set_test" lastpk:{fields:{name:"id" type:INT32 charset:63 flags:49667} rows:{lengths:1 values:"2"}}}}} keyspace:"commerce" shard:"0" type:COMMIT keyspace:"commerce" shard:"0"] +[type:BEGIN keyspace:"commerce" shard:"0" type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/156f702a-0d47-11ef-8723-653d045ab990:1-50"}} keyspace:"commerce" shard:"0" type:COMMIT keyspace:"commerce" shard:"0"] +[type:COPY_COMPLETED keyspace:"commerce" shard:"0" type:COPY_COMPLETED] +[type:BEGIN timestamp:1715179399 current_time:1715179399817221000 keyspace:"commerce" shard:"0" type:FIELD timestamp:1715179399 field_event:{table_name:"commerce.enum_set_test" fields:{name:"id" type:INT32 table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"id" column_length:11 charset:63 flags:49667 column_type:"int"} fields:{name:"name" type:VARCHAR table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"name" column_length:480 charset:255 column_type:"varchar(120)"} fields:{name:"shirt_size" type:ENUM table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"shirt_size" column_length:28 charset:255 flags:256 column_type:"enum('small','medium','large','xlarge','xxlarge')"} fields:{name:"hobbies" type:SET table:"enum_set_test" org_table:"enum_set_test" database:"vt_commerce" org_name:"hobbies" column_length:288 charset:255 flags:2048 column_type:"set('knitting','cooking','pickleball','biking','hiking','motorcycle','video games','reading')"} keyspace:"commerce" shard:"0" enum_set_string_values:true} current_time:1715179399821735000 keyspace:"commerce" shard:"0" type:ROW timestamp:1715179399 row_event:{table_name:"commerce.enum_set_test" row_changes:{after:{lengths:1 lengths:9 lengths:6 lengths:55 values:"3Matt Lordmediumpickleball,biking,hiking,motorcycle,video games,reading"}} keyspace:"commerce" shard:"0" flags:1} current_time:1715179399821762000 keyspace:"commerce" shard:"0" type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/156f702a-0d47-11ef-8723-653d045ab990:1-51"}} keyspace:"commerce" shard:"0" type:COMMIT timestamp:1715179399 current_time:1715179399821801000 keyspace:"commerce" shard:"0"] +[type:BEGIN timestamp:1715179399 current_time:1715179399822310000 keyspace:"commerce" shard:"0" type:ROW timestamp:1715179399 row_event:{table_name:"commerce.enum_set_test" row_changes:{after:{lengths:1 lengths:15 lengths:5 lengths:0 values:"4Jerry Badyellowlarge"}} keyspace:"commerce" shard:"0" flags:1} current_time:1715179399822355000 keyspace:"commerce" shard:"0" type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/156f702a-0d47-11ef-8723-653d045ab990:1-52"}} keyspace:"commerce" shard:"0" type:COMMIT timestamp:1715179399 current_time:1715179399822360000 keyspace:"commerce" shard:"0"] +[type:BEGIN timestamp:1715179400 current_time:1715179400512056000 keyspace:"commerce" shard:"0" type:ROW timestamp:1715179400 row_event:{table_name:"commerce.enum_set_test" row_changes:{before:{lengths:1 lengths:9 lengths:6 lengths:23 values:"2Sally Maemediumknitting,cooking,hiking"} after:{lengths:1 lengths:9 lengths:5 lengths:31 values:"2Sally Maesmallknitting,cooking,hiking,reading"}} keyspace:"commerce" shard:"0" flags:1} current_time:1715179400512094000 keyspace:"commerce" shard:"0" type:VGTID vgtid:{shard_gtids:{keyspace:"commerce" shard:"0" gtid:"MySQL56/156f702a-0d47-11ef-8723-653d045ab990:1-53"}} keyspace:"commerce" shard:"0" type:COMMIT timestamp:1715179400 current_time:1715179400512108000 keyspace:"commerce" shard:"0"] +``` + +An example key difference there being that `after:{lengths:1 lengths:9 lengths:1 lengths:3 values:"2Sally Mae1147"}` from Vitess v19 and older becomes `after:{lengths:1 lengths:9 lengths:5 lengths:31 values:"2Sally Maesmallknitting,cooking,hiking,reading"}` from Vitess v20 and newer. So `1` -> `small` and `147` -> `knitting,cooking,hiking,reading` for the `ENUM` and `SET` column values respectively. This also demonstrates why this mapping is necessary in consumers/clients, as `147` has no logical meaning/value for this column outside of MySQL internals. + +If you're using the [`Debezium` Vitess connector](https://debezium.io/documentation/reference/stable/connectors/vitess.html), you should upgrade your connector to 2.7 (the next release) — which should contain [the relevant necessary changes](https://issues.redhat.com/browse/DBZ-7792) — *prior to upgrading Vitess* to v20.0.1 or later. If you're using any of the PlanetScale connectors ([`AirByte`](https://github.com/planetscale/airbyte-source/), [`FiveTran`](https://github.com/planetscale/fivetran-source), or [`singer-tap`](https://github.com/planetscale/singer-tap)) then no actions are required. + +If you're using a custom `VStream` client/consumer, then you will need to build a new client with the updated v20 [binlogdata protos](https://pkg.go.dev/vitess.io/vitess/go/vt/proto/binlogdata) ([source](https://github.com/vitessio/vitess/blob/main/proto/binlogdata.proto) for which would be in `main` or the `release-20.0` branch) before needing to support Vitess v20.0.1 or later. Your client will then be able to handle old and new messages, with older messages always having this new field set to `false`. + +#### `shutdown_grace_period` Default Change + +The `--shutdown_grace_period` flag, which was introduced in v2 with a default of `0 seconds`, has now been changed to default to `3 seconds`. +This makes reparenting in Vitess resilient to client errors, and prevents PlannedReparentShard from timing out. + +In order to preserve the old behaviour, the users can set the flag back to `0 seconds` causing open transactions to never be shutdown, but in that case, they run the risk of PlannedReparentShard calls timing out. + +#### New `unmanaged` Flag and `disable_active_reparents` deprecation + +New flag `--unmanaged` has been introduced in this release to make it easier to flag unmanaged tablets. It also runs validations to make sure the unmanaged tablets are configured properly. `--disable_active_reparents` flag has been deprecated for `vttablet`, `vtcombo` and `vttestserver` binaries and will be removed in future releases. Specifying the `--unmanaged` flag will also block replication commands and replication repairs. + +Starting this release, all unmanaged tablets should specify this flag. + + +#### `recovery-period-block-duration` Flag deprecation + +The flag `--recovery-period-block-duration` has been deprecated in VTOrc from this release. Its value is now ignored and the flag will be removed in later releases. +VTOrc no longer blocks recoveries for a certain duration after a previous recovery has completed. Since VTOrc refreshes the required information after +acquiring a shard lock, blocking of recoveries is not required. + +#### `mysqlctld` `onterm_timeout` Default Change + +The `--onterm_timeout` flag default value has changed for `mysqlctld`. It now is by default long enough to be able to wait for the default `--shutdown-wait-time` when shutting down on a `TERM` signal. + +This is necessary since otherwise MySQL would never shut down cleanly with the old defaults, since `mysqlctld` would shut down already after 10 seconds by default. + +#### `MoveTables` now removes `auto_increment` clauses by default when moving tables from an unsharded keyspace to a sharded one + +A new `--remove-sharded-auto-increment` flag has been added to the [`MoveTables` create sub-command](https://vitess.io/docs/20.0/reference/programs/vtctldclient/vtctldclient_movetables/vtctldclient_movetables_create/) and it is set to `true` by default. This flag controls whether any [MySQL `auto_increment`](https://dev.mysql.com/doc/refman/en/example-auto-increment.html) clauses should be removed from the table definitions when moving tables from an unsharded keyspace to a sharded one. This is now done by default as `auto_increment` clauses should not typically be used with sharded tables and you should instead rely on externally generated values such as a form of universally/globally unique identifiers or use [Vitess sequences](https://vitess.io/docs/reference/features/vitess-sequences/) in order to ensure that each row has a unique identifier (Primary Key value) across all shards. If for some reason you want to retain them you can set this new flag to `false` when creating the workflow. + +#### `Durabler` interface method renaming + +The methods of [the `Durabler` interface](https://github.com/vitessio/vitess/blob/main/go/vt/vtctl/reparentutil/durability.go#L70-L79) in `go/vt/vtctl/reparentutil` were renamed to be public _(capitalized)_ methods to make it easier to integrate custom Durability Policies from external packages. See [RFC for details](https://github.com/vitessio/vitess/issues/15544). + +Users of custom Durability Policies must rename private `Durabler` methods. + +Changes: +- The `promotionRule` method was renamed to `PromotionRule` +- The `semiSyncAckers` method was renamed to `SemiSyncAckers` +- The `isReplicaSemiSync` method was renamed to `IsReplicaSemiSync` + +### Query Compatibility + +#### Vindex Hints + +Vitess now supports Vindex hints that provide a way for users to influence the shard routing of queries in Vitess by specifying, which vindexes should be considered or ignored by the query planner. This feature enhances the control over query execution, allowing for potentially more efficient data access patterns in sharded databases. + +Example: + ```sql + SELECT * FROM user USE VINDEX (hash_user_id, secondary_vindex) WHERE user_id = 123; + SELECT * FROM order IGNORE VINDEX (range_order_id) WHERE order_date = '2021-01-01'; + ``` + +For more information about Vindex hints and its usage, please consult the documentation. + +#### Update with Limit Support + +Support is added for sharded update with limit. + +Example: `update t1 set t1.foo = 'abc', t1.bar = 23 where t1.baz > 5 limit 1` + +More details about how it works is available in [MySQL Docs](https://dev.mysql.com/doc/refman/8.0/en/update.html) + +#### Update with Multi Table Support + +Support is added for sharded multi-table update with column update on single target table using multiple table join. + +Example: `update t1 join t2 on t1.id = t2.id join t3 on t1.col = t3.col set t1.baz = 'abc', t1.apa = 23 where t3.foo = 5 and t2.bar = 7` + +More details about how it works is available in [MySQL Docs](https://dev.mysql.com/doc/refman/8.0/en/update.html) + +#### Update with Multi Target Support + +Support is added for sharded multi table target update. + +Example: `update t1 join t2 on t1.id = t2.id set t1.foo = 'abc', t2.bar = 23` + +More details about how it works is available in [MySQL Docs](https://dev.mysql.com/doc/refman/8.0/en/update.html) + +#### Delete with Subquery Support + +Support is added for sharded table delete with subquery + +Example: `delete from t1 where id in (select col from t2 where foo = 32 and bar = 43)` + +#### Delete with Multi Target Support + +Support is added for sharded multi table target delete. + +Example: `delete t1, t3 from t1 join t2 on t1.id = t2.id join t3 on t1.col = t3.col` + +More details about how it works is available in [MySQL Docs](https://dev.mysql.com/doc/refman/8.0/en/delete.html) + +#### User Defined Functions Support + +VTGate can track any user defined functions for better planning. +User Defined Functions (UDFs) should be directly loaded in the underlying MySQL. + +It should be enabled in VTGate with the `--track-udfs` flag. +This will enable the tracking of UDFs in VTGate and will be used for planning. +Without this flag, VTGate will not be aware that there might be aggregating user-defined functions in the query that need to be pushed down to MySQL. + +More details about how to load UDFs is available in [MySQL Docs](https://dev.mysql.com/doc/extending-mysql/8.0/en/adding-loadable-function.html) + +#### Insert Row Alias Support + +Support is added to have row alias in Insert statement to be used with `on duplicate key update`. + +Example: +- `insert into user(id, name, email) valies (100, 'Alice', 'alice@mail.com') as new on duplicate key update name = new.name, email = new.email` +- `insert into user(id, name, email) valies (100, 'Alice', 'alice@mail.com') as new(m, n, p) on duplicate key update name = n, email = p` + +More details about how it works is available in [MySQL Docs](https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html) + +### Query Timeout +On a query timeout, Vitess closed the connection using the `kill connection` statement. This leads to connection churn +which is not desirable in some cases. To avoid this, Vitess now uses the `kill query` statement to cancel the query. +This will only cancel the query and does not terminate the connection. + +### Flag Changes + +#### `pprof-http` Default Change + +The `--pprof-http` flag, which was introduced in v19 with a default of `true`, has now been changed to default to `false`. +This makes HTTP `pprof` endpoints now an *opt-in* feature, rather than opt-out. +To continue enabling these endpoints, explicitly set `--pprof-http` when starting up Vitess components. + +#### New `--healthcheck-dial-concurrency` flag + +The new `--healthcheck-dial-concurrency` flag defines the maximum number of healthcheck connections that can open concurrently. This limit is to avoid hitting Go runtime panics on deployments watching enough tablets [to hit the runtime's maximum thread limit of `10000`](https://pkg.go.dev/runtime/debug#SetMaxThreads) due to blocking network syscalls. This flag applies to `vtcombo`, `vtctld` and `vtgate` only and a value less than the runtime max thread limit _(`10000`)_ is recommended. + +#### New minimum for `--buffer_min_time_between_failovers` + +The `--buffer_min_time_between_failovers` `vttablet` flag now has a minimum value of `1s`. This is because a value of 0 can cause issues with the buffering mechanics resulting in unexpected and unnecessary query errors — in particular during `MoveTables SwitchTraffic` operations. If you are currently specifying a value of 0 for this flag then you will need to update the config value to 1s *prior to upgrading to v20 or later* as `vttablet` will report an error and terminate if you attempt to start it with a value of 0. + +#### New `--track-udfs` vtgate flag + +The new `--track-udfs` flag enables VTGate to track user defined functions for better planning. + +#### Help text fix for `--lock-timeout` + +The help text for the flag `--lock-timeout` was incorrect. We were documenting it as a flag that controlled the duration for which the shard lock was acquired. It is actually the maximum duration for which we wait while attempting to acquire a lock from the topology server. + +#### New `--querylog-sample-rate` flag + +The new flag `--querylog-sample-rate float` adds support for sampling queries based on a float value between 0.0 _(no logging)_ and 1.0 _(all queries logged)_. If configured, this filtering is applied after the existing `--querylog-filter-tag` filter. + +#### New `--tablet-filter-tags` flag + +The new flag `--tablet-filter-tags StringMap` adds support to VTGate for filtering tablets by tablet tag key/values, specified as comma-separated list of key:values. The tags of a tablet are defined by the VTTablet flag `--init_tags`, which is also defined as a comma-separated list of key:values. + +## Minor Changes + +### New Stats + +#### VTTablet Query Cache Hits and Misses + +VTTablet exposes two new counter stats: + + * `QueryCacheHits`: Query engine query cache hits + * `QueryCacheMisses`: Query engine query cache misses + +### VTTablet Query Text Characters Processed + +VTGate and VTTablet expose a new counter stat `QueryTextCharactersProcessed` to reflect the number of query text characters processed. + +VTGate groups this metric by Operation, Keyspace and TabletType. On VTTablet it is grouped by Table, Plan and optionally Workload. + +### `SIGHUP` reload of gRPC client static auth creds + +The internal gRPC client now caches the static auth credentials and supports reloading via the `SIGHUP` signal. Previous to v20 the credentials were not cached. They were re-loaded from disk on every use. + +### VTAdmin + +#### vtadmin-web updated to node v20.12.2 (LTS) + +Building `vtadmin-web` now requires node >= v20.12.0 (LTS). Breaking changes from v18 to v20 can be found at https://nodejs.org/en/blog/release/v20.12.0 -- with no known issues that apply to VTAdmin. +Full details on the node v20.12.2 release can be found at https://nodejs.org/en/blog/release/v20.12.2. + +#### Replaced highcharts with d3 + +The vtadmin-web UI no longer has a dependency on highcharts for licensing reasons. The tablet QPS, tablet VReplication QPS, and workflow streams lag charts have all been replaced by d3. We'll be iteratively improving the d3 charts until they reach feature parity with the original highcharts charts. + +------------ +The entire changelog for this release can be found [here](https://github.com/vitessio/vitess/blob/main/changelog/20.0/20.0.0/changelog.md). + +The release includes 410 merged Pull Requests. + +Thanks to all our contributors: @Aoang, @GuptaManan100, @Its-Maniaco, @Maniktherana, @VaibhavMalik4187, @ajm188, @aparajon, @app/dependabot, @app/github-actions, @app/vitess-bot, @arthurschreiber, @bddicken, @beingnoble03, @brendar, @crazeteam, @dbussink, @deepthi, @demmer, @derekperkins, @ejortegau, @frouioui, @harshit-gangal, @mattlord, @maxenglander, @mdlayher, @notfelineit, @pavedroad, @rafer, @rohit-nayak-ps, @rvrangel, @shlomi-noach, @systay, @timvaillancourt, @tycol7, @vitess-bot, @vmg, @wangweicugw, @whuang8, @yoheimuta + diff --git a/changelog/20.0/README.md b/changelog/20.0/README.md index 4fb70ae78c1..a143396b60c 100644 --- a/changelog/20.0/README.md +++ b/changelog/20.0/README.md @@ -1,2 +1,4 @@ ## v20.0 * **[20.0.0](20.0.0)** + * [Changelog](20.0.0/changelog.md) + * [Release Notes](20.0.0/release_notes.md) From db23b5f314f2157fa9770c762c9ed1df6da6e7c8 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:48:40 +0200 Subject: [PATCH 28/40] CI Bug: Rename shard name back to match existing workflow file for vreplication_migrate_vdiff2_convert_tz (#16148) Signed-off-by: Rohit Nayak --- .github/workflows/cluster_endtoend_22.yml | 150 ---------------------- test/ci_workflow_gen.go | 1 - test/config.json | 10 +- 3 files changed, 5 insertions(+), 156 deletions(-) delete mode 100644 .github/workflows/cluster_endtoend_22.yml diff --git a/.github/workflows/cluster_endtoend_22.yml b/.github/workflows/cluster_endtoend_22.yml deleted file mode 100644 index b94632fa223..00000000000 --- a/.github/workflows/cluster_endtoend_22.yml +++ /dev/null @@ -1,150 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (22) -on: [push, pull_request] -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (22)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - name: Run endtoend tests on Cluster (22) - runs-on: gh-hosted-runners-4cores-1 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check if workflow needs to be skipped - id: skip-workflow - run: | - skip='false' - if [[ "${{github.event.pull_request}}" == "" ]] && [[ "${{github.ref}}" != "refs/heads/main" ]] && [[ ! "${{github.ref}}" =~ ^refs/heads/release-[0-9]+\.[0-9]$ ]] && [[ ! "${{github.ref}}" =~ "refs/tags/.*" ]]; then - skip='true' - fi - echo Skip ${skip} - echo "skip-workflow=${skip}" >> $GITHUB_OUTPUT - - PR_DATA=$(curl -s\ - -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github.v3+json" \ - "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}") - draft=$(echo "$PR_DATA" | jq .draft -r) - echo "is_draft=${draft}" >> $GITHUB_OUTPUT - - - name: Check out code - if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: actions/checkout@v4 - - - name: Check for changes in relevant files - if: steps.skip-workflow.outputs.skip-workflow == 'false' - uses: dorny/paths-filter@v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_22.yml' - - - name: Set up Go - if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@v5 - with: - go-version: 1.22.4 - - - name: Set up python - if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@v5 - - - name: Tune the OS - if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' - run: | - # Limit local port range to not use ports that overlap with server side - # ports that we listen on. - sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - # Increase the asynchronous non-blocking I/O. More information at https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_use_native_aio - echo "fs.aio-max-nr = 1048576" | sudo tee -a /etc/sysctl.conf - sudo sysctl -p /etc/sysctl.conf - - - name: Get dependencies - if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' - run: | - - # Get key to latest MySQL repo - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys A8D3785C - # Setup MySQL 8.0 - wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb - echo mysql-apt-config mysql-apt-config/select-server select mysql-8.0 | sudo debconf-set-selections - sudo DEBIAN_FRONTEND="noninteractive" dpkg -i mysql-apt-config* - sudo apt-get -qq update - # Install everything else we need, and configure - sudo apt-get -qq install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata xz-utils libncurses5 - - sudo service mysql stop - sudo service etcd stop - sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ - sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld - go mod download - - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - - name: Setup launchable dependencies - if: steps.skip-workflow.outputs.is_draft == 'false' && steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # run the tests however you normally do, then produce a JUnit XML file - eatmydata -- go run test.go -docker=false -follow -shard 22 | tee -a output.txt | go-junit-report -set-exit-code > report.xml - - - name: Print test output and Record test result in launchable if PR is not a draft - if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() - run: | - if [[ "${{steps.skip-workflow.outputs.is_draft}}" == "false" ]]; then - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - fi - - # print test output - cat output.txt diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go index f1457f1be66..14b40976b2b 100644 --- a/test/ci_workflow_gen.go +++ b/test/ci_workflow_gen.go @@ -74,7 +74,6 @@ var ( "backup_pitr", "backup_pitr_xtrabackup", "21", - "22", "mysql_server_vault", "vstream", "onlineddl_vrepl", diff --git a/test/config.json b/test/config.json index 21c16af6caf..9f753f37ba8 100644 --- a/test/config.json +++ b/test/config.json @@ -1279,7 +1279,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestVtctldclientCLI", "-timeout", "20m"], "Command": [], "Manual": false, -"Shard": "vreplication_cli_migrate_vdiff2_convert_tz", + "Shard": "vreplication_migrate_vdiff2_convert_tz", "RetryMax": 1, "Tags": [] }, @@ -1288,7 +1288,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestVtctlMigrate", "-timeout", "30m"], "Command": [], "Manual": false, - "Shard": "vreplication_cli_migrate_vdiff2_convert_tz", + "Shard": "vreplication_migrate_vdiff2_convert_tz", "RetryMax": 1, "Tags": [] }, @@ -1297,7 +1297,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestVtctldMigrate", "-timeout", "30m"], "Command": [], "Manual": false, - "Shard": "vreplication_cli_migrate_vdiff2_convert_tz", + "Shard": "vreplication_migrate_vdiff2_convert_tz", "RetryMax": 1, "Tags": [] }, @@ -1306,7 +1306,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestVDiff2", "-timeout", "30m"], "Command": [], "Manual": false, - "Shard": "vreplication_cli_migrate_vdiff2_convert_tz", + "Shard": "vreplication_migrate_vdiff2_convert_tz", "RetryMax": 1, "Tags": [] }, @@ -1315,7 +1315,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestMoveTablesTZ"], "Command": [], "Manual": false, - "Shard": "vreplication_cli_migrate_vdiff2_convert_tz", + "Shard": "vreplication_migrate_vdiff2_convert_tz", "RetryMax": 1, "Tags": [] }, From fb9446bd383ff24b27c8e1478f016a138fe116f5 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:21:27 +0530 Subject: [PATCH 29/40] Fix dual merging in outer join queries (#15959) Signed-off-by: Manan Gupta --- go/test/endtoend/vtgate/gen4/gen4_test.go | 31 +++ .../planbuilder/operators/join_merging.go | 25 ++- go/vt/vtgate/planbuilder/operators/joins.go | 2 +- .../planbuilder/testdata/select_cases.json | 206 ++++++++++++++++++ 4 files changed, 253 insertions(+), 11 deletions(-) diff --git a/go/test/endtoend/vtgate/gen4/gen4_test.go b/go/test/endtoend/vtgate/gen4/gen4_test.go index f284f85e883..a242ef0bb7a 100644 --- a/go/test/endtoend/vtgate/gen4/gen4_test.go +++ b/go/test/endtoend/vtgate/gen4/gen4_test.go @@ -489,3 +489,34 @@ func TestPercentageAndUnderscore(t *testing.T) { mcmp.Exec(`select a.tcol1 from t2 a join t2 b where a.tcol1 = b.tcol2 group by a.tcol1 having repeat(a.tcol1,min(a.id)) = "C_DC_D" order by a.tcol1`) mcmp.Exec(`select a.tcol1 from t2 a join t2 b where a.tcol1 = b.tcol2 group by a.tcol1 having repeat(a.tcol1,min(a.id)) = "C\_DC\_D" order by a.tcol1`) } + +// TestDualJoinQueries tests that queries having a join between a dual query and another query work as intended. +func TestDualJoinQueries(t *testing.T) { + mcmp, closer := start(t) + defer closer() + + mcmp.Exec(`insert into t2(id, tcol1, tcol2) values (1, 'ABC', 'ABC'),(2, 'DEF', 'DEF')`) + + // Left join with a dual table on left - merge-able + mcmp.Exec("select t.title, t2.id from (select 'ABC' as title) as t left join t2 on t2.id=1 and t.title = t2.tcol1") + mcmp.Exec("select t.title, t2.id from (select 'DEF' as title) as t left join t2 on t2.id=1 and t.title = t2.tcol1") + + // Left join with a dual table on left - non-merge-able + mcmp.Exec("select t.title, t2.id from (select 'ABC' as title) as t left join t2 on t2.id < 2 and t.title = t2.tcol1") + mcmp.Exec("select t.title, t2.id from (select 'DEF' as title) as t left join t2 on t2.id < 2 and t.title = t2.tcol1") + + // right join with a dual table on left + mcmp.Exec("select t.title, t2.id from (select 'ABC' as title) as t right join t2 on t.title = t2.tcol1") + + // Right join with a dual table on right - merge-able + mcmp.Exec("select t.title, t2.id from t2 right join (select 'ABC' as title) as t on t2.id=1 and t.title = t2.tcol1") + mcmp.Exec("select t.title, t2.id from t2 right join (select 'DEF' as title) as t on t2.id=1 and t.title = t2.tcol1") + + // Right join with a dual table on right - non-merge-able + mcmp.Exec("select t.title, t2.id from t2 right join (select 'ABC' as title) as t on t2.id < 2 and t.title = t2.tcol1") + mcmp.Exec("select t.title, t2.id from t2 right join (select 'DEF' as title) as t on t2.id < 2 and t.title = t2.tcol1") + + // left join with a dual table on right + mcmp.Exec("select t.title, t2.id from t2 left join (select 'ABC' as title) as t on t.title = t2.tcol1") + +} diff --git a/go/vt/vtgate/planbuilder/operators/join_merging.go b/go/vt/vtgate/planbuilder/operators/join_merging.go index 5edc812b1b7..8bba8ba57d9 100644 --- a/go/vt/vtgate/planbuilder/operators/join_merging.go +++ b/go/vt/vtgate/planbuilder/operators/join_merging.go @@ -27,17 +27,28 @@ import ( // mergeJoinInputs checks whether two operators can be merged into a single one. // If they can be merged, a new operator with the merged routing is returned // If they cannot be merged, nil is returned. -func mergeJoinInputs(ctx *plancontext.PlanningContext, lhs, rhs Operator, joinPredicates []sqlparser.Expr, m merger) *Route { +func mergeJoinInputs(ctx *plancontext.PlanningContext, lhs, rhs Operator, joinPredicates []sqlparser.Expr, m *joinMerger) *Route { lhsRoute, rhsRoute, routingA, routingB, a, b, sameKeyspace := prepareInputRoutes(lhs, rhs) if lhsRoute == nil { return nil } switch { - // if either side is a dual query, we can always merge them together case a == dual: - return m.merge(ctx, lhsRoute, rhsRoute, routingB) + // We clone the right hand side and try and push all the join predicates that are solved entirely by that side. + // If a dual is on the left side and it is a left join (all right joins are changed to left joins), then we can only merge if the right side is a single sharded routing. + rhsClone := Clone(rhs).(*Route) + for _, predicate := range joinPredicates { + if ctx.SemTable.DirectDeps(predicate).IsSolvedBy(TableID(rhsClone)) { + rhsClone.AddPredicate(ctx, predicate) + } + } + if !m.joinType.IsInner() && !rhsClone.Routing.OpCode().IsSingleShard() { + return nil + } + return m.merge(ctx, lhsRoute, rhsClone, rhsClone.Routing) case b == dual: + // If a dual is on the right side. return m.merge(ctx, lhsRoute, rhsRoute, routingA) // an unsharded/reference route can be merged with anything going to that keyspace @@ -74,12 +85,6 @@ func prepareInputRoutes(lhs Operator, rhs Operator) (*Route, *Route, Routing, Ro lhsRoute, rhsRoute, routingA, routingB, sameKeyspace := getRoutesOrAlternates(lhsRoute, rhsRoute) a, b := getRoutingType(routingA), getRoutingType(routingB) - if getTypeName(routingA) < getTypeName(routingB) { - // while deciding if two routes can be merged, the LHS/RHS order of the routes is not important. - // for the actual merging, we still need to remember which side was inner and which was outer for subqueries - a, b = b, a - routingA, routingB = routingB, routingA - } return lhsRoute, rhsRoute, routingA, routingB, a, b, sameKeyspace } @@ -178,7 +183,7 @@ func getRoutingType(r Routing) routingType { panic(fmt.Sprintf("switch should be exhaustive, got %T", r)) } -func newJoinMerge(predicates []sqlparser.Expr, joinType sqlparser.JoinType) merger { +func newJoinMerge(predicates []sqlparser.Expr, joinType sqlparser.JoinType) *joinMerger { return &joinMerger{ predicates: predicates, joinType: joinType, diff --git a/go/vt/vtgate/planbuilder/operators/joins.go b/go/vt/vtgate/planbuilder/operators/joins.go index d0d0fa770c8..86cdf06fe7e 100644 --- a/go/vt/vtgate/planbuilder/operators/joins.go +++ b/go/vt/vtgate/planbuilder/operators/joins.go @@ -44,7 +44,7 @@ func AddPredicate( joinPredicates bool, newFilter func(Operator, sqlparser.Expr) Operator, ) Operator { - deps := ctx.SemTable.RecursiveDeps(expr) + deps := ctx.SemTable.DirectDeps(expr) switch { case deps.IsSolvedBy(TableID(join.GetLHS())): // predicates can always safely be pushed down to the lhs if that is all they depend on diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json index f94c75f084b..7cc1b58f7b0 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json @@ -2072,6 +2072,212 @@ ] } }, + { + "comment": "left join with a dual table on left - merge-able", + "query": "select t.title, user.col from (select 'hello' as title) as t left join user on user.id=1", + "plan": { + "QueryType": "SELECT", + "Original": "select t.title, user.col from (select 'hello' as title) as t left join user on user.id=1", + "Instructions": { + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select t.title, `user`.col from (select 'hello' as title from dual where 1 != 1) as t left join `user` on `user`.id = 1 where 1 != 1", + "Query": "select t.title, `user`.col from (select 'hello' as title from dual) as t left join `user` on `user`.id = 1", + "Table": "`user`, dual", + "Values": [ + "1" + ], + "Vindex": "user_index" + }, + "TablesUsed": [ + "main.dual", + "user.user" + ] + } + }, + { + "comment": "left join with a dual table on left - non-merge-able", + "query": "select t.title, user.col from (select 'hello' as title) as t left join user on user.id <= 4", + "plan": { + "QueryType": "SELECT", + "Original": "select t.title, user.col from (select 'hello' as title) as t left join user on user.id <= 4", + "Instructions": { + "OperatorType": "Join", + "Variant": "LeftJoin", + "JoinColumnIndexes": "L:0,R:0", + "TableName": "dual_`user`", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Reference", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select t.title from (select 'hello' as title from dual where 1 != 1) as t where 1 != 1", + "Query": "select t.title from (select 'hello' as title from dual) as t", + "Table": "dual" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `user`.col from `user` where 1 != 1", + "Query": "select `user`.col from `user` where `user`.id <= 4", + "Table": "`user`" + } + ] + }, + "TablesUsed": [ + "main.dual", + "user.user" + ] + } + }, + { + "comment": "left join with dual non-merge-able with predicate with cross dependencies", + "query": "select t.title, user.col from (select 'hello' as title) as t left join user on user.id <= 4 and t.title = user.col", + "plan": { + "QueryType": "SELECT", + "Original": "select t.title, user.col from (select 'hello' as title) as t left join user on user.id <= 4 and t.title = user.col", + "Instructions": { + "OperatorType": "Join", + "Variant": "LeftJoin", + "JoinColumnIndexes": "L:0,R:0", + "JoinVars": { + "t_title": 0 + }, + "TableName": "dual_`user`", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Reference", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select t.title from (select 'hello' as title from dual where 1 != 1) as t where 1 != 1", + "Query": "select t.title from (select 'hello' as title from dual) as t", + "Table": "dual" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `user`.col from `user` where 1 != 1", + "Query": "select `user`.col from `user` where `user`.col = :t_title and `user`.id <= 4", + "Table": "`user`" + } + ] + }, + "TablesUsed": [ + "main.dual", + "user.user" + ] + } + }, + { + "comment": "right join with a dual table on left", + "query": "select t.title, user.col from (select 'hello' as title) as t right join user on user.id<=4", + "plan": { + "QueryType": "SELECT", + "Original": "select t.title, user.col from (select 'hello' as title) as t right join user on user.id<=4", + "Instructions": { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select t.title, `user`.col from `user` left join (select 'hello' as title from dual where 1 != 1) as t on `user`.id <= 4 where 1 != 1", + "Query": "select t.title, `user`.col from `user` left join (select 'hello' as title from dual) as t on `user`.id <= 4", + "Table": "`user`, dual" + }, + "TablesUsed": [ + "main.dual", + "user.user" + ] + } + }, + { + "comment": "right join with a dual table on right - merge-able", + "query": "select t.title, user.col from user right join (select 'hello' as title) as t on user.id=1", + "plan": { + "QueryType": "SELECT", + "Original": "select t.title, user.col from user right join (select 'hello' as title) as t on user.id=1", + "Instructions": { + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select t.title, `user`.col from (select 'hello' as title from dual where 1 != 1) as t left join `user` on `user`.id = 1 where 1 != 1", + "Query": "select t.title, `user`.col from (select 'hello' as title from dual) as t left join `user` on `user`.id = 1", + "Table": "`user`, dual", + "Values": [ + "1" + ], + "Vindex": "user_index" + }, + "TablesUsed": [ + "main.dual", + "user.user" + ] + } + }, + { + "comment": "right join with a dual table on right - non-merge-able", + "query": "select t.title, user.col from user right join (select 'hello' as title) as t on user.id>=4", + "plan": { + "QueryType": "SELECT", + "Original": "select t.title, user.col from user right join (select 'hello' as title) as t on user.id>=4", + "Instructions": { + "OperatorType": "Join", + "Variant": "LeftJoin", + "JoinColumnIndexes": "L:0,R:0", + "TableName": "dual_`user`", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Reference", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select t.title from (select 'hello' as title from dual where 1 != 1) as t where 1 != 1", + "Query": "select t.title from (select 'hello' as title from dual) as t", + "Table": "dual" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select `user`.col from `user` where 1 != 1", + "Query": "select `user`.col from `user` where `user`.id >= 4", + "Table": "`user`" + } + ] + }, + "TablesUsed": [ + "main.dual", + "user.user" + ] + } + }, { "comment": "Union after into outfile is incorrect", "query": "select id from user into outfile 'out_file_name' union all select id from music", From 113f3754b98089adaa93ab93828135f2c2661fe2 Mon Sep 17 00:00:00 2001 From: Arthur Schreiber Date: Thu, 13 Jun 2024 12:40:55 +0200 Subject: [PATCH 30/40] Fix `vtexplain` not handling `UNION` queries with `weight_string` results correctly. (#16129) Signed-off-by: Arthur Schreiber --- .../multi-output/selectsharded-output.txt | 42 +++++++++++-------- .../multi-output/updatesharded-output.txt | 4 +- .../testdata/selectsharded-queries.sql | 4 +- go/vt/vtexplain/vtexplain_test.go | 23 ++++++++++ go/vt/vtexplain/vtexplain_vttablet.go | 12 ++++-- 5 files changed, 61 insertions(+), 24 deletions(-) diff --git a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt index 7ae20ca1a7f..57e1ee00c42 100644 --- a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt +++ b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt @@ -91,18 +91,18 @@ select name, count(*) from user group by name /* scatter aggregate */ ---------------------------------------------------------------------- select 1, "hello", 3.14, null from user limit 10 /* select constant sql values */ -1 ks_sharded/-40: select 1, 'hello', 3.14, null from `user` limit 10 /* select constant sql values */ -1 ks_sharded/40-80: select 1, 'hello', 3.14, null from `user` limit 10 /* select constant sql values */ -1 ks_sharded/80-c0: select 1, 'hello', 3.14, null from `user` limit 10 /* select constant sql values */ -1 ks_sharded/c0-: select 1, 'hello', 3.14, null from `user` limit 10 /* select constant sql values */ +1 ks_sharded/-40: select 1, 'hello', 3.14, null from `user` limit 10 /* INT64 */ /* select constant sql values */ +1 ks_sharded/40-80: select 1, 'hello', 3.14, null from `user` limit 10 /* INT64 */ /* select constant sql values */ +1 ks_sharded/80-c0: select 1, 'hello', 3.14, null from `user` limit 10 /* INT64 */ /* select constant sql values */ +1 ks_sharded/c0-: select 1, 'hello', 3.14, null from `user` limit 10 /* INT64 */ /* select constant sql values */ ---------------------------------------------------------------------- select * from (select id from user) s /* scatter paren select */ -1 ks_sharded/-40: select s.id from (select id from `user`) as s limit 10001 /* scatter paren select */ -1 ks_sharded/40-80: select s.id from (select id from `user`) as s limit 10001 /* scatter paren select */ -1 ks_sharded/80-c0: select s.id from (select id from `user`) as s limit 10001 /* scatter paren select */ -1 ks_sharded/c0-: select s.id from (select id from `user`) as s limit 10001 /* scatter paren select */ +1 ks_sharded/-40: select id from (select id from `user`) as s limit 10001 /* scatter paren select */ +1 ks_sharded/40-80: select id from (select id from `user`) as s limit 10001 /* scatter paren select */ +1 ks_sharded/80-c0: select id from (select id from `user`) as s limit 10001 /* scatter paren select */ +1 ks_sharded/c0-: select id from (select id from `user`) as s limit 10001 /* scatter paren select */ ---------------------------------------------------------------------- select name from user where id = (select id from t1) /* non-correlated subquery as value */ @@ -114,21 +114,21 @@ select name from user where id = (select id from t1) /* non-correlated subquery select name from user where id in (select id from t1) /* non-correlated subquery in IN clause */ 1 ks_unsharded/-: select id from t1 limit 10001 /* non-correlated subquery in IN clause */ -2 ks_sharded/-40: select `name` from `user` where 1 = 1 and id in (1) limit 10001 /* non-correlated subquery in IN clause */ +2 ks_sharded/-40: select `name` from `user` where 1 and id in (1) limit 10001 /* non-correlated subquery in IN clause */ ---------------------------------------------------------------------- select name from user where id not in (select id from t1) /* non-correlated subquery in NOT IN clause */ 1 ks_unsharded/-: select id from t1 limit 10001 /* non-correlated subquery in NOT IN clause */ -2 ks_sharded/-40: select `name` from `user` where 1 = 0 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ -2 ks_sharded/40-80: select `name` from `user` where 1 = 0 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ -2 ks_sharded/80-c0: select `name` from `user` where 1 = 0 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ -2 ks_sharded/c0-: select `name` from `user` where 1 = 0 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ +2 ks_sharded/-40: select `name` from `user` where not 1 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ +2 ks_sharded/40-80: select `name` from `user` where not 1 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ +2 ks_sharded/80-c0: select `name` from `user` where not 1 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ +2 ks_sharded/c0-: select `name` from `user` where not 1 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ ---------------------------------------------------------------------- select name from user where exists (select id from t1) /* non-correlated subquery as EXISTS */ -1 ks_unsharded/-: select 1 from t1 limit 1 /* non-correlated subquery as EXISTS */ +1 ks_unsharded/-: select 1 from t1 limit 10001 /* non-correlated subquery as EXISTS */ 2 ks_sharded/-40: select `name` from `user` where 1 limit 10001 /* non-correlated subquery as EXISTS */ 2 ks_sharded/40-80: select `name` from `user` where 1 limit 10001 /* non-correlated subquery as EXISTS */ 2 ks_sharded/80-c0: select `name` from `user` where 1 limit 10001 /* non-correlated subquery as EXISTS */ @@ -137,10 +137,10 @@ select name from user where exists (select id from t1) /* non-correlated subquer ---------------------------------------------------------------------- select * from name_info order by info /* select * and order by varchar column */ -1 ks_sharded/-40: select `name`, info from name_info order by info asc limit 10001 /* select * and order by varchar column */ -1 ks_sharded/40-80: select `name`, info from name_info order by info asc limit 10001 /* select * and order by varchar column */ -1 ks_sharded/80-c0: select `name`, info from name_info order by info asc limit 10001 /* select * and order by varchar column */ -1 ks_sharded/c0-: select `name`, info from name_info order by info asc limit 10001 /* select * and order by varchar column */ +1 ks_sharded/-40: select `name`, info, weight_string(info) from name_info order by name_info.info asc limit 10001 /* select * and order by varchar column */ +1 ks_sharded/40-80: select `name`, info, weight_string(info) from name_info order by name_info.info asc limit 10001 /* select * and order by varchar column */ +1 ks_sharded/80-c0: select `name`, info, weight_string(info) from name_info order by name_info.info asc limit 10001 /* select * and order by varchar column */ +1 ks_sharded/c0-: select `name`, info, weight_string(info) from name_info order by name_info.info asc limit 10001 /* select * and order by varchar column */ ---------------------------------------------------------------------- select distinct(name) from user where id = 1 /* select distinct */ @@ -207,3 +207,9 @@ SELECT id FROM orders WHERE id IN (1, "1", 1) 2 ks_sharded/40-80: select id from orders where id in (1, '1', 1) limit 10001 ---------------------------------------------------------------------- +(SELECT user.id, user.name FROM user WHERE user.id = 1) UNION (SELECT user.id, user.name FROM user WHERE user.id = 2) + +2 ks_sharded/-40: select dt.c0 as id, dt.c1 as `name`, weight_string(dt.c0), weight_string(dt.c1) from (select distinct `user`.id, `user`.`name` from `user` where `user`.id = 2) as dt(c0, c1) limit 10001 +2 ks_sharded/-40: select dt.c0 as id, dt.c1 as `name`, weight_string(dt.c0), weight_string(dt.c1) from (select distinct `user`.id, `user`.`name` from `user` where `user`.id = 1) as dt(c0, c1) limit 10001 + +---------------------------------------------------------------------- diff --git a/go/vt/vtexplain/testdata/multi-output/updatesharded-output.txt b/go/vt/vtexplain/testdata/multi-output/updatesharded-output.txt index b5e055bd856..ee9727efc11 100644 --- a/go/vt/vtexplain/testdata/multi-output/updatesharded-output.txt +++ b/go/vt/vtexplain/testdata/multi-output/updatesharded-output.txt @@ -128,10 +128,10 @@ update user set nickname='alice' where id in (1,4) 1 ks_sharded/-40: begin 1 ks_sharded/-40: savepoint x1 -1 ks_sharded/-40: update `user` set nickname = 'alice' where id in (1, 4) limit 10001 +1 ks_sharded/-40: update `user` set nickname = 'alice' where id in (1) limit 10001 1 ks_sharded/c0-: begin 1 ks_sharded/c0-: savepoint x1 -1 ks_sharded/c0-: update `user` set nickname = 'alice' where id in (1, 4) limit 10001 +1 ks_sharded/c0-: update `user` set nickname = 'alice' where id in (4) limit 10001 ---------------------------------------------------------------------- commit diff --git a/go/vt/vtexplain/testdata/selectsharded-queries.sql b/go/vt/vtexplain/testdata/selectsharded-queries.sql index ad003d1c457..a68b5c49073 100644 --- a/go/vt/vtexplain/testdata/selectsharded-queries.sql +++ b/go/vt/vtexplain/testdata/selectsharded-queries.sql @@ -38,4 +38,6 @@ select id from user where not id in (select col from music where music.user_id = SELECT user.id, user.name, name_info.info FROM user INNER JOIN music ON (user.id = music.user_id) LEFT OUTER JOIN name_info ON (user.name = name_info.name); -SELECT id FROM orders WHERE id IN (1, "1", 1) +SELECT id FROM orders WHERE id IN (1, "1", 1); + +(SELECT user.id, user.name FROM user WHERE user.id = 1) UNION (SELECT user.id, user.name FROM user WHERE user.id = 2); diff --git a/go/vt/vtexplain/vtexplain_test.go b/go/vt/vtexplain/vtexplain_test.go index 49bb94fedb1..ed32d0698db 100644 --- a/go/vt/vtexplain/vtexplain_test.go +++ b/go/vt/vtexplain/vtexplain_test.go @@ -35,6 +35,7 @@ import ( "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/key" + querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv/tabletenvtest" @@ -151,6 +152,28 @@ func TestExplain(t *testing.T) { } tests := []test{ {"unsharded", defaultTestOpts()}, + {"selectsharded", defaultTestOpts()}, + {"insertsharded", defaultTestOpts()}, + {"updatesharded", defaultTestOpts()}, + {"deletesharded", defaultTestOpts()}, + {"comments", defaultTestOpts()}, + {"options", &Options{ + ReplicationMode: "STATEMENT", + NumShards: 4, + Normalize: false, + }}, + {"target", &Options{ + ReplicationMode: "ROW", + NumShards: 4, + Normalize: false, + Target: "ks_sharded/40-80", + }}, + {"gen4", &Options{ + ReplicationMode: "ROW", + NumShards: 4, + Normalize: true, + PlannerVersion: querypb.ExecuteOptions_Gen4, + }}, } for _, tst := range tests { diff --git a/go/vt/vtexplain/vtexplain_vttablet.go b/go/vt/vtexplain/vtexplain_vttablet.go index 28e7431ad82..3f9aee0efa3 100644 --- a/go/vt/vtexplain/vtexplain_vttablet.go +++ b/go/vt/vtexplain/vtexplain_vttablet.go @@ -864,9 +864,15 @@ func inferColTypeFromExpr(node sqlparser.Expr, tableColumnMap map[sqlparser.Iden colTypes = append(colTypes, colType) } case sqlparser.Callable: - // As a shortcut, functions are integral types - colNames = append(colNames, sqlparser.String(node)) - colTypes = append(colTypes, querypb.Type_INT32) + switch node := node.(type) { + case *sqlparser.WeightStringFuncExpr: + colNames = append(colNames, sqlparser.String(node)) + colTypes = append(colTypes, querypb.Type_BINARY) + default: + // As a shortcut, functions are integral types + colNames = append(colNames, sqlparser.String(node)) + colTypes = append(colTypes, querypb.Type_INT32) + } case *sqlparser.Literal: colNames = append(colNames, sqlparser.String(node)) switch node.Type { From e4e40eaf56da193401de2af3c8457cb6165a373c Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Thu, 13 Jun 2024 17:37:43 +0530 Subject: [PATCH 31/40] CI Summary Addition (#16143) Signed-off-by: Manan Gupta --- .github/workflows/cluster_endtoend_12.yml | 7 +++++++ .github/workflows/cluster_endtoend_13.yml | 7 +++++++ .github/workflows/cluster_endtoend_15.yml | 7 +++++++ .github/workflows/cluster_endtoend_18.yml | 7 +++++++ .github/workflows/cluster_endtoend_21.yml | 7 +++++++ .github/workflows/cluster_endtoend_backup_pitr.yml | 7 +++++++ .../workflows/cluster_endtoend_backup_pitr_xtrabackup.yml | 7 +++++++ .../cluster_endtoend_ers_prs_newfeatures_heavy.yml | 7 +++++++ .github/workflows/cluster_endtoend_mysql80.yml | 7 +++++++ .github/workflows/cluster_endtoend_mysql_server_vault.yml | 7 +++++++ .github/workflows/cluster_endtoend_onlineddl_revert.yml | 7 +++++++ .github/workflows/cluster_endtoend_onlineddl_scheduler.yml | 7 +++++++ .github/workflows/cluster_endtoend_onlineddl_vrepl.yml | 7 +++++++ .../workflows/cluster_endtoend_onlineddl_vrepl_stress.yml | 7 +++++++ .../cluster_endtoend_onlineddl_vrepl_stress_suite.yml | 7 +++++++ .../workflows/cluster_endtoend_onlineddl_vrepl_suite.yml | 7 +++++++ .github/workflows/cluster_endtoend_schemadiff_vrepl.yml | 7 +++++++ .../workflows/cluster_endtoend_tabletmanager_consul.yml | 7 +++++++ .../workflows/cluster_endtoend_tabletmanager_tablegc.yml | 7 +++++++ .../cluster_endtoend_tabletmanager_throttler_topo.yml | 7 +++++++ .../workflows/cluster_endtoend_topo_connection_cache.yml | 7 +++++++ .../cluster_endtoend_vreplication_across_db_versions.yml | 7 +++++++ .github/workflows/cluster_endtoend_vreplication_basic.yml | 7 +++++++ .../workflows/cluster_endtoend_vreplication_cellalias.yml | 7 +++++++ .../cluster_endtoend_vreplication_copy_parallel.yml | 7 +++++++ .../cluster_endtoend_vreplication_foreign_key_stress.yml | 7 +++++++ .../cluster_endtoend_vreplication_mariadb_to_mysql.yml | 7 +++++++ ...ter_endtoend_vreplication_migrate_vdiff2_convert_tz.yml | 7 +++++++ .../cluster_endtoend_vreplication_multi_tenant.yml | 7 +++++++ ...end_vreplication_partial_movetables_and_materialize.yml | 7 +++++++ .github/workflows/cluster_endtoend_vreplication_v2.yml | 7 +++++++ .github/workflows/cluster_endtoend_vstream.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtbackup.yml | 7 +++++++ ...ster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml | 7 +++++++ .../workflows/cluster_endtoend_vtgate_concurrentdml.yml | 7 +++++++ .../cluster_endtoend_vtgate_foreignkey_stress.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_gen4.yml | 7 +++++++ .../workflows/cluster_endtoend_vtgate_general_heavy.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_godriver.yml | 7 +++++++ .../workflows/cluster_endtoend_vtgate_partial_keyspace.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_queries.yml | 7 +++++++ .../workflows/cluster_endtoend_vtgate_readafterwrite.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_reservedconn.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_schema.yml | 7 +++++++ .../workflows/cluster_endtoend_vtgate_schema_tracker.yml | 7 +++++++ .../cluster_endtoend_vtgate_tablet_healthcheck_cache.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_topo.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_topo_consul.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_topo_etcd.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_transaction.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_unsharded.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtgate_vschema.yml | 7 +++++++ .github/workflows/cluster_endtoend_vtorc.yml | 7 +++++++ .github/workflows/cluster_endtoend_vttablet_prscomplex.yml | 7 +++++++ .github/workflows/cluster_endtoend_xb_backup.yml | 7 +++++++ .github/workflows/cluster_endtoend_xb_recovery.yml | 7 +++++++ .github/workflows/unit_test_evalengine_mysql57.yml | 7 +++++++ .github/workflows/unit_test_evalengine_mysql80.yml | 7 +++++++ .github/workflows/unit_test_mysql57.yml | 7 +++++++ .github/workflows/unit_test_mysql80.yml | 7 +++++++ test/templates/cluster_endtoend_test.tpl | 7 +++++++ test/templates/cluster_endtoend_test_mysql57.tpl | 7 +++++++ test/templates/unit_test.tpl | 7 +++++++ 64 files changed, 448 insertions(+) diff --git a/.github/workflows/cluster_endtoend_12.yml b/.github/workflows/cluster_endtoend_12.yml index 7c98dc21e03..1049077d9d8 100644 --- a/.github/workflows/cluster_endtoend_12.yml +++ b/.github/workflows/cluster_endtoend_12.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_13.yml b/.github/workflows/cluster_endtoend_13.yml index 86695e274cd..f79e0c7b0fa 100644 --- a/.github/workflows/cluster_endtoend_13.yml +++ b/.github/workflows/cluster_endtoend_13.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_15.yml b/.github/workflows/cluster_endtoend_15.yml index d9090153390..ec3b339ff40 100644 --- a/.github/workflows/cluster_endtoend_15.yml +++ b/.github/workflows/cluster_endtoend_15.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_18.yml b/.github/workflows/cluster_endtoend_18.yml index 9f02fe391e1..f80566e9f34 100644 --- a/.github/workflows/cluster_endtoend_18.yml +++ b/.github/workflows/cluster_endtoend_18.yml @@ -153,3 +153,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_21.yml b/.github/workflows/cluster_endtoend_21.yml index f2bfd7c86d4..f6979a49abc 100644 --- a/.github/workflows/cluster_endtoend_21.yml +++ b/.github/workflows/cluster_endtoend_21.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_backup_pitr.yml b/.github/workflows/cluster_endtoend_backup_pitr.yml index a8d81803f22..847fd84ae08 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml index c514999d150..a2a83812c23 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml @@ -151,3 +151,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml index 3059c3a3403..401185596d7 100644 --- a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml +++ b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml @@ -166,3 +166,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_mysql80.yml b/.github/workflows/cluster_endtoend_mysql80.yml index c2740f08370..8cbbdfb4607 100644 --- a/.github/workflows/cluster_endtoend_mysql80.yml +++ b/.github/workflows/cluster_endtoend_mysql80.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_mysql_server_vault.yml b/.github/workflows/cluster_endtoend_mysql_server_vault.yml index 9414da50b31..e6a75d6b70b 100644 --- a/.github/workflows/cluster_endtoend_mysql_server_vault.yml +++ b/.github/workflows/cluster_endtoend_mysql_server_vault.yml @@ -153,3 +153,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_onlineddl_revert.yml b/.github/workflows/cluster_endtoend_onlineddl_revert.yml index 8b55bb716dd..76766f1bfa6 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_revert.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_revert.yml @@ -149,3 +149,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml index 153442fa236..0c685c4599c 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml @@ -149,3 +149,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml index e90465ff31e..a63ad54c2c3 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml @@ -153,3 +153,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml index 13bfb04f43e..20c378695e0 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml @@ -153,3 +153,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml index c7d8de9f21a..3dfcd2cc99b 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml @@ -153,3 +153,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml index 75e2d2bcbaf..92dab0a55f1 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml @@ -153,3 +153,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml index 2f2ecdceb01..be568217503 100644 --- a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml +++ b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml @@ -153,3 +153,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml index 3cbec4b81f2..bf6c8e8e87c 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml @@ -153,3 +153,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml index 07eb70d1348..4d63b3a0cf1 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml index 1446042c7cc..700e78ac55d 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_topo_connection_cache.yml b/.github/workflows/cluster_endtoend_topo_connection_cache.yml index 03542a9f014..3119d085c18 100644 --- a/.github/workflows/cluster_endtoend_topo_connection_cache.yml +++ b/.github/workflows/cluster_endtoend_topo_connection_cache.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml index a9fa2711c65..4d622675dcb 100644 --- a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml +++ b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vreplication_basic.yml b/.github/workflows/cluster_endtoend_vreplication_basic.yml index 09a354b1701..1c0b8f922d8 100644 --- a/.github/workflows/cluster_endtoend_vreplication_basic.yml +++ b/.github/workflows/cluster_endtoend_vreplication_basic.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml index 46f2ff602fb..96f30d4835a 100644 --- a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml +++ b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml b/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml index bd4ea33ca7c..aae735aa7ec 100644 --- a/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml +++ b/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml index be47a10d6cf..f0ef175a170 100644 --- a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml +++ b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml b/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml index 40196062a2e..d2bb0a3d099 100644 --- a/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml +++ b/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml b/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml index 278cdaa5d24..1f6dfb6b7ef 100644 --- a/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml +++ b/.github/workflows/cluster_endtoend_vreplication_migrate_vdiff2_convert_tz.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml b/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml index ef0dbe4f7d2..f44ddf1d27f 100644 --- a/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml +++ b/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml index 7b05b9acf1e..a1074fa2553 100644 --- a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml +++ b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vreplication_v2.yml b/.github/workflows/cluster_endtoend_vreplication_v2.yml index 183aa917b8d..1ee0bc3d5d0 100644 --- a/.github/workflows/cluster_endtoend_vreplication_v2.yml +++ b/.github/workflows/cluster_endtoend_vreplication_v2.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vstream.yml b/.github/workflows/cluster_endtoend_vstream.yml index 9065b6dcc21..3f1399eece4 100644 --- a/.github/workflows/cluster_endtoend_vstream.yml +++ b/.github/workflows/cluster_endtoend_vstream.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtbackup.yml b/.github/workflows/cluster_endtoend_vtbackup.yml index 0f7abc581e3..ef96875687a 100644 --- a/.github/workflows/cluster_endtoend_vtbackup.yml +++ b/.github/workflows/cluster_endtoend_vtbackup.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml index 760a4b3edd7..63574ed2858 100644 --- a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml @@ -166,3 +166,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml index ff51270d6c7..ca050f090eb 100644 --- a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml +++ b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml index 048f6209b9c..edcca203c4a 100644 --- a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml +++ b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_gen4.yml b/.github/workflows/cluster_endtoend_vtgate_gen4.yml index 45792956826..8f0071a4815 100644 --- a/.github/workflows/cluster_endtoend_vtgate_gen4.yml +++ b/.github/workflows/cluster_endtoend_vtgate_gen4.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml index 9d2cb912597..37b318650a9 100644 --- a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml @@ -166,3 +166,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_godriver.yml b/.github/workflows/cluster_endtoend_vtgate_godriver.yml index 1e52f4a6024..79daa318661 100644 --- a/.github/workflows/cluster_endtoend_vtgate_godriver.yml +++ b/.github/workflows/cluster_endtoend_vtgate_godriver.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml index e742efc1b16..fc2540b5809 100644 --- a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml +++ b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_queries.yml b/.github/workflows/cluster_endtoend_vtgate_queries.yml index 0410ef04354..8813a2ca6ac 100644 --- a/.github/workflows/cluster_endtoend_vtgate_queries.yml +++ b/.github/workflows/cluster_endtoend_vtgate_queries.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml index 4d9b9c72fb2..e4863b23353 100644 --- a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml +++ b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml index b8e3aa878b2..0296b040b3a 100644 --- a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml +++ b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_schema.yml b/.github/workflows/cluster_endtoend_vtgate_schema.yml index 463044caeae..5d1c36c0e3f 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml index 3bf1f6b2547..1436f891744 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml index a88c0bebb3b..f04fce0e634 100644 --- a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml +++ b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_topo.yml b/.github/workflows/cluster_endtoend_vtgate_topo.yml index 0101eba229a..5954f98e1ac 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml index 12fc3e5d5f3..a67db05bde6 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml @@ -153,3 +153,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml index 184353b2731..190c934ac5f 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_transaction.yml b/.github/workflows/cluster_endtoend_vtgate_transaction.yml index e85a919902d..a3210624126 100644 --- a/.github/workflows/cluster_endtoend_vtgate_transaction.yml +++ b/.github/workflows/cluster_endtoend_vtgate_transaction.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml index 314d1dde312..30dce8c0d6c 100644 --- a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml +++ b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml index 9ed165fbd17..0a80cb59e88 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml @@ -166,3 +166,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtgate_vschema.yml b/.github/workflows/cluster_endtoend_vtgate_vschema.yml index 3731b54376f..dbc55e05eaf 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vschema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vschema.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vtorc.yml b/.github/workflows/cluster_endtoend_vtorc.yml index fc65f0c126a..04f3ac33a30 100644 --- a/.github/workflows/cluster_endtoend_vtorc.yml +++ b/.github/workflows/cluster_endtoend_vtorc.yml @@ -157,3 +157,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml index 6ee747c28ab..451cf6013cc 100644 --- a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml +++ b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml @@ -148,3 +148,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_xb_backup.yml b/.github/workflows/cluster_endtoend_xb_backup.yml index c407a83d9ca..551e98116d5 100644 --- a/.github/workflows/cluster_endtoend_xb_backup.yml +++ b/.github/workflows/cluster_endtoend_xb_backup.yml @@ -151,3 +151,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/cluster_endtoend_xb_recovery.yml b/.github/workflows/cluster_endtoend_xb_recovery.yml index 0e18e301f51..1648f4d8fb6 100644 --- a/.github/workflows/cluster_endtoend_xb_recovery.yml +++ b/.github/workflows/cluster_endtoend_xb_recovery.yml @@ -151,3 +151,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/unit_test_evalengine_mysql57.yml b/.github/workflows/unit_test_evalengine_mysql57.yml index 70583c4216a..1a979b122a3 100644 --- a/.github/workflows/unit_test_evalengine_mysql57.yml +++ b/.github/workflows/unit_test_evalengine_mysql57.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/unit_test_evalengine_mysql80.yml b/.github/workflows/unit_test_evalengine_mysql80.yml index d5d90ebb912..c00217a172a 100644 --- a/.github/workflows/unit_test_evalengine_mysql80.yml +++ b/.github/workflows/unit_test_evalengine_mysql80.yml @@ -167,3 +167,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/unit_test_mysql57.yml b/.github/workflows/unit_test_mysql57.yml index 03ecf100e72..cf708f0b117 100644 --- a/.github/workflows/unit_test_mysql57.yml +++ b/.github/workflows/unit_test_mysql57.yml @@ -170,3 +170,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/unit_test_mysql80.yml b/.github/workflows/unit_test_mysql80.yml index d6a0b1bd08c..7dac5c3eb96 100644 --- a/.github/workflows/unit_test_mysql80.yml +++ b/.github/workflows/unit_test_mysql80.yml @@ -167,3 +167,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/test/templates/cluster_endtoend_test.tpl b/test/templates/cluster_endtoend_test.tpl index c6837170c20..7532b51bb6e 100644 --- a/test/templates/cluster_endtoend_test.tpl +++ b/test/templates/cluster_endtoend_test.tpl @@ -219,3 +219,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/test/templates/cluster_endtoend_test_mysql57.tpl b/test/templates/cluster_endtoend_test_mysql57.tpl index c22d394c8c5..eaa9e366196 100644 --- a/test/templates/cluster_endtoend_test_mysql57.tpl +++ b/test/templates/cluster_endtoend_test_mysql57.tpl @@ -224,3 +224,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/test/templates/unit_test.tpl b/test/templates/unit_test.tpl index 17782da2fa1..ca31dcbcaf9 100644 --- a/test/templates/unit_test.tpl +++ b/test/templates/unit_test.tpl @@ -184,3 +184,10 @@ jobs: # print test output cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" From e9bdc39d93abdd5ae38a126b988e4bcfe3a6dbac Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 13 Jun 2024 18:00:35 +0300 Subject: [PATCH 32/40] Docker: Update node vtadmin version (#16147) Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- docker/binaries/vtadmin/Dockerfile | 2 +- docker/local/install_local_dependencies.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/binaries/vtadmin/Dockerfile b/docker/binaries/vtadmin/Dockerfile index 9d30ba565e0..fe69237ea13 100644 --- a/docker/binaries/vtadmin/Dockerfile +++ b/docker/binaries/vtadmin/Dockerfile @@ -17,7 +17,7 @@ ARG DEBIAN_VER=bullseye-slim FROM vitess/lite:${VT_BASE_VER} AS lite -FROM node:18-${DEBIAN_VER} as node +FROM node:20-${DEBIAN_VER} as node # Prepare directory structure. RUN mkdir -p /vt/web diff --git a/docker/local/install_local_dependencies.sh b/docker/local/install_local_dependencies.sh index e570d0dc196..07fd302e283 100755 --- a/docker/local/install_local_dependencies.sh +++ b/docker/local/install_local_dependencies.sh @@ -22,4 +22,4 @@ mkdir -p /var/run/etcd && chown -R vitess:vitess /var/run/etcd rm -rf /var/lib/apt/lists/* # Install npm and node dependencies for vtadmin -curl -fsSL https://deb.nodesource.com/setup_19.x | bash - && apt-get install -y nodejs +curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs From 8a01d032f33092df1fc0ef0059d9b735f6bc4028 Mon Sep 17 00:00:00 2001 From: Arthur Schreiber Date: Thu, 13 Jun 2024 18:39:57 +0200 Subject: [PATCH 33/40] Fix flakiness in `vtexplain` unit test case. (#16159) --- .../testdata/multi-output/selectsharded-output.txt | 6 +++--- go/vt/vtexplain/testdata/selectsharded-queries.sql | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt index 57e1ee00c42..fea0d7c7de6 100644 --- a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt +++ b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt @@ -207,9 +207,9 @@ SELECT id FROM orders WHERE id IN (1, "1", 1) 2 ks_sharded/40-80: select id from orders where id in (1, '1', 1) limit 10001 ---------------------------------------------------------------------- -(SELECT user.id, user.name FROM user WHERE user.id = 1) UNION (SELECT user.id, user.name FROM user WHERE user.id = 2) +(SELECT user.id, user.name FROM user WHERE user.id = 1) UNION (SELECT user.id, user.name FROM user WHERE user.id = 3) -2 ks_sharded/-40: select dt.c0 as id, dt.c1 as `name`, weight_string(dt.c0), weight_string(dt.c1) from (select distinct `user`.id, `user`.`name` from `user` where `user`.id = 2) as dt(c0, c1) limit 10001 -2 ks_sharded/-40: select dt.c0 as id, dt.c1 as `name`, weight_string(dt.c0), weight_string(dt.c1) from (select distinct `user`.id, `user`.`name` from `user` where `user`.id = 1) as dt(c0, c1) limit 10001 +1 ks_sharded/-40: select dt.c0 as id, dt.c1 as `name`, weight_string(dt.c0), weight_string(dt.c1) from (select distinct `user`.id, `user`.`name` from `user` where `user`.id = 1) as dt(c0, c1) limit 10001 +1 ks_sharded/40-80: select dt.c0 as id, dt.c1 as `name`, weight_string(dt.c0), weight_string(dt.c1) from (select distinct `user`.id, `user`.`name` from `user` where `user`.id = 3) as dt(c0, c1) limit 10001 ---------------------------------------------------------------------- diff --git a/go/vt/vtexplain/testdata/selectsharded-queries.sql b/go/vt/vtexplain/testdata/selectsharded-queries.sql index a68b5c49073..067f53df4e6 100644 --- a/go/vt/vtexplain/testdata/selectsharded-queries.sql +++ b/go/vt/vtexplain/testdata/selectsharded-queries.sql @@ -40,4 +40,4 @@ SELECT user.id, user.name, name_info.info FROM user INNER JOIN music ON (user.id SELECT id FROM orders WHERE id IN (1, "1", 1); -(SELECT user.id, user.name FROM user WHERE user.id = 1) UNION (SELECT user.id, user.name FROM user WHERE user.id = 2); +(SELECT user.id, user.name FROM user WHERE user.id = 1) UNION (SELECT user.id, user.name FROM user WHERE user.id = 3); From cd17de9b93dacf960559409ba33d9d2ab9759460 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Thu, 13 Jun 2024 22:53:11 +0530 Subject: [PATCH 34/40] Add Summary in unit-race workflow (#16164) Signed-off-by: Manan Gupta --- .github/workflows/unit_race.yml | 9 ++++++++- .github/workflows/unit_race_evalengine.yml | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml index c07bad84490..277a29df216 100644 --- a/.github/workflows/unit_race.yml +++ b/.github/workflows/unit_race.yml @@ -143,4 +143,11 @@ jobs: fi # print test output - cat output.txt \ No newline at end of file + cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" diff --git a/.github/workflows/unit_race_evalengine.yml b/.github/workflows/unit_race_evalengine.yml index 0de2d60a5ae..02ac005a0a5 100644 --- a/.github/workflows/unit_race_evalengine.yml +++ b/.github/workflows/unit_race_evalengine.yml @@ -143,4 +143,11 @@ jobs: fi # print test output - cat output.txt \ No newline at end of file + cat output.txt + + - name: Test Summary + if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.unit_tests == 'true' && always() + uses: test-summary/action@v2 + with: + paths: "report.xml" + show: "fail, skip" From 1f1852868f44376f9a01bdce7a0c1a79b3abaabf Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Fri, 14 Jun 2024 16:01:55 +0530 Subject: [PATCH 35/40] fix flaky test TestQueryTimeoutWithShardTargeting (#16150) Signed-off-by: Harshit Gangal --- .../vtgate/queries/timeout/timeout_test.go | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/go/test/endtoend/vtgate/queries/timeout/timeout_test.go b/go/test/endtoend/vtgate/queries/timeout/timeout_test.go index a8202cd5593..f7bd96dca13 100644 --- a/go/test/endtoend/vtgate/queries/timeout/timeout_test.go +++ b/go/test/endtoend/vtgate/queries/timeout/timeout_test.go @@ -111,19 +111,18 @@ func TestQueryTimeoutWithShardTargeting(t *testing.T) { // insert some data utils.Exec(t, mcmp.VtConn, "insert into t1(id1, id2) values (1,2),(3,4),(4,5),(5,6)") - // insert - _, err := utils.ExecAllowError(t, mcmp.VtConn, "insert /*vt+ QUERY_TIMEOUT_MS=1 */ into t1(id1, id2) values (6,sleep(5))") - assert.ErrorContains(t, err, "context deadline exceeded (errno 1317) (sqlstate 70100)") - - // update - _, err = utils.ExecAllowError(t, mcmp.VtConn, "update /*vt+ QUERY_TIMEOUT_MS=1 */ t1 set id2 = sleep(5)") - assert.ErrorContains(t, err, "context deadline exceeded (errno 1317) (sqlstate 70100)") - - // delete - _, err = utils.ExecAllowError(t, mcmp.VtConn, "delete /*vt+ QUERY_TIMEOUT_MS=1 */ from t1 where id2 = sleep(5)") - assert.ErrorContains(t, err, "context deadline exceeded (errno 1317) (sqlstate 70100)") + queries := []string{ + "insert /*vt+ QUERY_TIMEOUT_MS=1 */ into t1(id1, id2) values (6,sleep(5))", + "update /*vt+ QUERY_TIMEOUT_MS=1 */ t1 set id2 = sleep(5)", + "delete /*vt+ QUERY_TIMEOUT_MS=1 */ from t1 where id2 = sleep(5)", + "select /*vt+ QUERY_TIMEOUT_MS=1 */ 1 from t1 where id2 = 5 and sleep(100)", + } - // select - _, err = utils.ExecAllowError(t, mcmp.VtConn, "select /*vt+ QUERY_TIMEOUT_MS=1 */ 1 from t1 where id2 = 5 and sleep(100)") - assert.ErrorContains(t, err, "context deadline exceeded (errno 1317) (sqlstate 70100)") + for _, query := range queries { + t.Run(query, func(t *testing.T) { + _, err := utils.ExecAllowError(t, mcmp.VtConn, query) + assert.ErrorContains(t, err, "context deadline exceeded") + assert.ErrorContains(t, err, "(errno 1317) (sqlstate 70100)") + }) + } } From a3fc54d7bbc2ddd8893796cf43231b2f88d77a86 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Fri, 14 Jun 2024 18:37:20 +0530 Subject: [PATCH 36/40] fix: rows affected count for multi table update for non-literal column value (#16181) Signed-off-by: Harshit Gangal --- go/vt/vtgate/engine/dml_with_input.go | 2 +- go/vt/vtgate/engine/dml_with_input_test.go | 76 ++++++++++++++++++++++ go/vt/vtgate/engine/fake_vcursor_test.go | 2 +- 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/go/vt/vtgate/engine/dml_with_input.go b/go/vt/vtgate/engine/dml_with_input.go index 0974f753cef..e0eb3b03592 100644 --- a/go/vt/vtgate/engine/dml_with_input.go +++ b/go/vt/vtgate/engine/dml_with_input.go @@ -146,7 +146,7 @@ func executeNonLiteralUpdate(ctx context.Context, vcursor VCursor, bindVars map[ if res == nil { res = qr } else { - res.RowsAffected += res.RowsAffected + res.RowsAffected += qr.RowsAffected } } return res, nil diff --git a/go/vt/vtgate/engine/dml_with_input_test.go b/go/vt/vtgate/engine/dml_with_input_test.go index b41dc9e148c..6fcf2040dfc 100644 --- a/go/vt/vtgate/engine/dml_with_input_test.go +++ b/go/vt/vtgate/engine/dml_with_input_test.go @@ -20,6 +20,7 @@ import ( "context" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqltypes" @@ -180,3 +181,78 @@ func TestDeleteWithMultiTarget(t *testing.T) { `ExecuteMultiShard ks.-20: dummy_delete_2 {dml_vals: type:TUPLE values:{type:TUPLE value:"\x89\x02\x03100\x89\x02\x011"} values:{type:TUPLE value:"\x89\x02\x03100\x89\x02\x012"} values:{type:TUPLE value:"\x89\x02\x03200\x89\x02\x013"}} true true`, }) } + +// TestUpdateWithInputNonLiteral test the case where the column updated have non literal update. +// Therefore, update query should be executed for each row in the input result. +// This also validates the output rows affected. +func TestUpdateWithInputNonLiteral(t *testing.T) { + input := &fakePrimitive{results: []*sqltypes.Result{ + sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col|val", "int64|varchar|int64"), "1|a|100", "2|b|200", "3|c|300"), + }} + + dml := &DMLWithInput{ + Input: input, + DMLs: []Primitive{&Update{ + DML: &DML{ + RoutingParameters: &RoutingParameters{ + Opcode: Scatter, + Keyspace: &vindexes.Keyspace{ + Name: "ks", + Sharded: true, + }, + }, + Query: "dummy_update", + }, + }}, + OutputCols: [][]int{{1, 0}}, + BVList: []map[string]int{ + {"bv1": 2}, + }, + } + + vc := newDMLTestVCursor("-20", "20-") + vc.results = []*sqltypes.Result{ + {RowsAffected: 1}, {RowsAffected: 1}, {RowsAffected: 1}, + } + qr, err := dml.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false) + require.NoError(t, err) + vc.ExpectLog(t, []string{ + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ` + + `ks.-20: dummy_update {bv1: type:INT64 value:"100" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01a\x89\x02\x011"}} ` + + `ks.20-: dummy_update {bv1: type:INT64 value:"100" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01a\x89\x02\x011"}} true false`, + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ` + + `ks.-20: dummy_update {bv1: type:INT64 value:"200" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01b\x89\x02\x012"}} ` + + `ks.20-: dummy_update {bv1: type:INT64 value:"200" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01b\x89\x02\x012"}} true false`, + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ` + + `ks.-20: dummy_update {bv1: type:INT64 value:"300" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01c\x89\x02\x013"}} ` + + `ks.20-: dummy_update {bv1: type:INT64 value:"300" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01c\x89\x02\x013"}} true false`, + }) + assert.EqualValues(t, 3, qr.RowsAffected) + + vc.Rewind() + input.rewind() + err = dml.TryStreamExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, false, + func(result *sqltypes.Result) error { + qr = result + return nil + }) + require.NoError(t, err) + vc.ExpectLog(t, []string{ + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ` + + `ks.-20: dummy_update {bv1: type:INT64 value:"100" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01a\x89\x02\x011"}} ` + + `ks.20-: dummy_update {bv1: type:INT64 value:"100" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01a\x89\x02\x011"}} true false`, + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ` + + `ks.-20: dummy_update {bv1: type:INT64 value:"200" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01b\x89\x02\x012"}} ` + + `ks.20-: dummy_update {bv1: type:INT64 value:"200" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01b\x89\x02\x012"}} true false`, + `ResolveDestinations ks [] Destinations:DestinationAllShards()`, + `ExecuteMultiShard ` + + `ks.-20: dummy_update {bv1: type:INT64 value:"300" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01c\x89\x02\x013"}} ` + + `ks.20-: dummy_update {bv1: type:INT64 value:"300" dml_vals: type:TUPLE values:{type:TUPLE value:"\x950\x01c\x89\x02\x013"}} true false`, + }) + assert.EqualValues(t, 3, qr.RowsAffected) +} diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index 08a40c0d835..1ba0abfa2ef 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -803,7 +803,7 @@ func (f *loggingVCursor) nextResult() (*sqltypes.Result, error) { if r == nil { return &sqltypes.Result{}, f.resultErr } - return r, nil + return r.Copy(), nil } func (f *loggingVCursor) CanUseSetVar() bool { From ec1ca6f7deecc9342b278ab79a060dec78c7e43c Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Fri, 14 Jun 2024 18:39:48 +0530 Subject: [PATCH 37/40] Adding Distributed Transaction Test (#16114) Signed-off-by: Harshit Gangal --- .../vtgate/transaction/twopc/main_test.go | 271 +++++++++ .../vtgate/transaction/twopc/schema.sql | 12 + .../vtgate/transaction/twopc/twopc_test.go | 523 ++++++++++++++++++ .../vtgate/transaction/twopc/vschema.json | 26 + go/vt/vttablet/tabletserver/twopc.go | 6 +- test/config.json | 9 + 6 files changed, 846 insertions(+), 1 deletion(-) create mode 100644 go/test/endtoend/vtgate/transaction/twopc/main_test.go create mode 100644 go/test/endtoend/vtgate/transaction/twopc/schema.sql create mode 100644 go/test/endtoend/vtgate/transaction/twopc/twopc_test.go create mode 100644 go/test/endtoend/vtgate/transaction/twopc/vschema.json diff --git a/go/test/endtoend/vtgate/transaction/twopc/main_test.go b/go/test/endtoend/vtgate/transaction/twopc/main_test.go new file mode 100644 index 00000000000..102235d672a --- /dev/null +++ b/go/test/endtoend/vtgate/transaction/twopc/main_test.go @@ -0,0 +1,271 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package transaction + +import ( + "context" + _ "embed" + "encoding/json" + "flag" + "fmt" + "io" + "os" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/endtoend/cluster" + "vitess.io/vitess/go/test/endtoend/utils" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/vtgate/vtgateconn" +) + +var ( + clusterInstance *cluster.LocalProcessCluster + vtParams mysql.ConnParams + vtgateGrpcAddress string + keyspaceName = "ks" + cell = "zone1" + hostname = "localhost" + sidecarDBName = "vt_ks" + + //go:embed schema.sql + SchemaSQL string + + //go:embed vschema.json + VSchema string +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + exitcode := func() int { + clusterInstance = cluster.NewCluster(cell, hostname) + defer clusterInstance.Teardown() + + // Start topo server + if err := clusterInstance.StartTopo(); err != nil { + return 1 + } + + // Reserve vtGate port in order to pass it to vtTablet + clusterInstance.VtgateGrpcPort = clusterInstance.GetAndReservePort() + + // Set extra args for twopc + clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, + "--transaction_mode", "TWOPC", + ) + clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, + "--twopc_enable", + "--twopc_coordinator_address", fmt.Sprintf("localhost:%d", clusterInstance.VtgateGrpcPort), + "--twopc_abandon_age", "3600", + "--queryserver-config-transaction-cap", "3", + ) + + // Start keyspace + keyspace := &cluster.Keyspace{ + Name: keyspaceName, + SchemaSQL: SchemaSQL, + VSchema: VSchema, + SidecarDBName: sidecarDBName, + } + if err := clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 1, false); err != nil { + return 1 + } + + // Start Vtgate + if err := clusterInstance.StartVtgate(); err != nil { + return 1 + } + vtParams = clusterInstance.GetVTParams(keyspaceName) + vtgateGrpcAddress = fmt.Sprintf("%s:%d", clusterInstance.Hostname, clusterInstance.VtgateGrpcPort) + + return m.Run() + }() + os.Exit(exitcode) +} + +func start(t *testing.T) (*mysql.Conn, func()) { + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + + deleteAll := func() { + tables := []string{"twopc_user"} + for _, table := range tables { + _, _ = utils.ExecAllowError(t, conn, "delete from "+table) + } + } + + deleteAll() + + return conn, func() { + deleteAll() + conn.Close() + cluster.PanicHandler(t) + } +} + +type extractInterestingValues func(dtidMap map[string]string, vals []sqltypes.Value) []sqltypes.Value + +var tables = map[string]extractInterestingValues{ + "ks.dt_state": func(dtidMap map[string]string, vals []sqltypes.Value) (out []sqltypes.Value) { + dtid := getDTID(dtidMap, vals[0].ToString()) + dtState := getDTState(vals[1]) + out = append(out, sqltypes.NewVarChar(dtid), sqltypes.NewVarChar(dtState.String())) + return + }, + "ks.dt_participant": func(dtidMap map[string]string, vals []sqltypes.Value) (out []sqltypes.Value) { + dtid := getDTID(dtidMap, vals[0].ToString()) + out = append([]sqltypes.Value{sqltypes.NewVarChar(dtid)}, vals[1:]...) + return + }, + "ks.redo_state": func(dtidMap map[string]string, vals []sqltypes.Value) (out []sqltypes.Value) { + dtid := getDTID(dtidMap, vals[0].ToString()) + dtState := getDTState(vals[1]) + out = append(out, sqltypes.NewVarChar(dtid), sqltypes.NewVarChar(dtState.String())) + return + }, + "ks.redo_statement": func(dtidMap map[string]string, vals []sqltypes.Value) (out []sqltypes.Value) { + dtid := getDTID(dtidMap, vals[0].ToString()) + out = append([]sqltypes.Value{sqltypes.NewVarChar(dtid)}, vals[1:]...) + return + }, + "ks.twopc_user": func(_ map[string]string, vals []sqltypes.Value) []sqltypes.Value { return vals }, +} + +func getDTState(val sqltypes.Value) querypb.TransactionState { + s, _ := val.ToInt() + return querypb.TransactionState(s) +} + +func getDTID(dtidMap map[string]string, dtKey string) string { + dtid, exists := dtidMap[dtKey] + if !exists { + dtid = fmt.Sprintf("dtid-%d", len(dtidMap)+1) + dtidMap[dtKey] = dtid + } + return dtid +} + +func runVStream(t *testing.T, ctx context.Context, ch chan *binlogdatapb.VEvent, vtgateConn *vtgateconn.VTGateConn) { + vgtid := &binlogdatapb.VGtid{ + ShardGtids: []*binlogdatapb.ShardGtid{ + {Keyspace: keyspaceName, Shard: "-80", Gtid: "current"}, + {Keyspace: keyspaceName, Shard: "80-", Gtid: "current"}, + }} + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*/", + }}, + } + vReader, err := vtgateConn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, nil) + require.NoError(t, err) + + // Use a channel to signal that the first VGTID event has been processed + firstEventProcessed := make(chan struct{}) + var once sync.Once + + go func() { + for { + evs, err := vReader.Recv() + if err == io.EOF || ctx.Err() != nil { + return + } + require.NoError(t, err) + + for _, ev := range evs { + // Signal the first event has been processed using sync.Once + if ev.Type == binlogdatapb.VEventType_VGTID { + once.Do(func() { close(firstEventProcessed) }) + } + if ev.Type == binlogdatapb.VEventType_ROW || ev.Type == binlogdatapb.VEventType_FIELD { + ch <- ev + } + } + } + }() + + // Wait for the first event to be processed + <-firstEventProcessed +} + +func retrieveTransitions(t *testing.T, ch chan *binlogdatapb.VEvent, tableMap map[string][]*querypb.Field, dtMap map[string]string) map[string][]string { + logTable := make(map[string][]string) + + keepWaiting := true + for keepWaiting { + select { + case re := <-ch: + if re.RowEvent != nil { + shard := re.RowEvent.Shard + tableName := re.RowEvent.TableName + fields, ok := tableMap[tableName] + require.Truef(t, ok, "table %s not found in fields map", tableName) + for _, rc := range re.RowEvent.RowChanges { + logEvent(logTable, dtMap, shard, tableName, fields, rc) + } + } + if re.FieldEvent != nil { + tableMap[re.FieldEvent.TableName] = re.FieldEvent.Fields + } + case <-time.After(1 * time.Second): + keepWaiting = false + } + } + return logTable +} + +func logEvent(logTable map[string][]string, dtMap map[string]string, shard string, tbl string, fields []*querypb.Field, rc *binlogdatapb.RowChange) { + key := fmt.Sprintf("%s:%s", tbl, shard) + + var eventType string + var vals []sqltypes.Value + switch { + case rc.Before == nil && rc.After == nil: + panic("do not expect row event with both before and after nil") + case rc.Before == nil: + eventType = "insert" + vals = sqltypes.MakeRowTrusted(fields, rc.After) + case rc.After == nil: + eventType = "delete" + vals = sqltypes.MakeRowTrusted(fields, rc.Before) + default: + eventType = "update" + vals = sqltypes.MakeRowTrusted(fields, rc.After) + } + execFunc, exists := tables[tbl] + if exists { + vals = execFunc(dtMap, vals) + } + logTable[key] = append(logTable[key], fmt.Sprintf("%s:%v", eventType, vals)) +} + +func prettyPrint(v interface{}) string { + b, err := json.MarshalIndent(v, "", " ") + if err != nil { + return fmt.Sprintf("got error marshalling: %v", err) + } + return string(b) +} diff --git a/go/test/endtoend/vtgate/transaction/twopc/schema.sql b/go/test/endtoend/vtgate/transaction/twopc/schema.sql new file mode 100644 index 00000000000..60a7c19837c --- /dev/null +++ b/go/test/endtoend/vtgate/transaction/twopc/schema.sql @@ -0,0 +1,12 @@ +create table twopc_user ( + id bigint, + name varchar(64), + primary key (id) +) Engine=InnoDB; + +create table twopc_music ( + id varchar(64), + user_id bigint, + title varchar(64), + primary key (id) +) Engine=InnoDB; \ No newline at end of file diff --git a/go/test/endtoend/vtgate/transaction/twopc/twopc_test.go b/go/test/endtoend/vtgate/transaction/twopc/twopc_test.go new file mode 100644 index 00000000000..f18073c5827 --- /dev/null +++ b/go/test/endtoend/vtgate/transaction/twopc/twopc_test.go @@ -0,0 +1,523 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package transaction + +import ( + "context" + _ "embed" + "reflect" + "sort" + "sync" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/test/endtoend/cluster" + "vitess.io/vitess/go/test/endtoend/utils" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" +) + +// TestDTCommit tests distributed transaction commit for insert, update and delete operations +// It verifies the binlog events for the same with transaction state changes and redo statements. +func TestDTCommit(t *testing.T) { + conn, closer := start(t) + defer closer() + + vtgateConn, err := cluster.DialVTGate(context.Background(), t.Name(), vtgateGrpcAddress, "fk_user", "") + require.NoError(t, err) + defer vtgateConn.Close() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ch := make(chan *binlogdatapb.VEvent) + runVStream(t, ctx, ch, vtgateConn) + + // Insert into multiple shards + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "insert into twopc_user(id, name) values(7,'foo')") + utils.Exec(t, conn, "insert into twopc_user(id, name) values(8,'bar')") + utils.Exec(t, conn, "insert into twopc_user(id, name) values(9,'baz')") + utils.Exec(t, conn, "insert into twopc_user(id, name) values(10,'apa')") + utils.Exec(t, conn, "commit") + + tableMap := make(map[string][]*querypb.Field) + dtMap := make(map[string]string) + logTable := retrieveTransitions(t, ch, tableMap, dtMap) + expectations := map[string][]string{ + "ks.dt_state:80-": { + "insert:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + "update:[VARCHAR(\"dtid-1\") VARCHAR(\"COMMIT\")]", + "delete:[VARCHAR(\"dtid-1\") VARCHAR(\"COMMIT\")]", + }, + "ks.dt_participant:80-": { + "insert:[VARCHAR(\"dtid-1\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + }, + "ks.redo_state:-80": { + "insert:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + "delete:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + }, + "ks.redo_statement:-80": { + "insert:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"insert into twopc_user(id, `name`) values (8, 'bar')\")]", + "insert:[VARCHAR(\"dtid-1\") INT64(2) BLOB(\"insert into twopc_user(id, `name`) values (10, 'apa')\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"insert into twopc_user(id, `name`) values (8, 'bar')\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(2) BLOB(\"insert into twopc_user(id, `name`) values (10, 'apa')\")]", + }, + "ks.twopc_user:-80": { + `insert:[INT64(8) VARCHAR("bar")]`, + `insert:[INT64(10) VARCHAR("apa")]`, + }, + "ks.twopc_user:80-": { + `insert:[INT64(7) VARCHAR("foo")]`, + `insert:[INT64(9) VARCHAR("baz")]`, + }, + } + assert.Equal(t, expectations, logTable, + "mismatch expected: \n got: %s, want: %s", prettyPrint(logTable), prettyPrint(expectations)) + + // Update from multiple shard + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "update twopc_user set name='newfoo' where id = 7") + utils.Exec(t, conn, "update twopc_user set name='newfoo' where id = 8") + utils.Exec(t, conn, "commit") + + logTable = retrieveTransitions(t, ch, tableMap, dtMap) + expectations = map[string][]string{ + "ks.dt_state:80-": { + "insert:[VARCHAR(\"dtid-2\") VARCHAR(\"PREPARE\")]", + "update:[VARCHAR(\"dtid-2\") VARCHAR(\"COMMIT\")]", + "delete:[VARCHAR(\"dtid-2\") VARCHAR(\"COMMIT\")]", + }, + "ks.dt_participant:80-": { + "insert:[VARCHAR(\"dtid-2\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + "delete:[VARCHAR(\"dtid-2\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + }, + "ks.redo_state:-80": { + "insert:[VARCHAR(\"dtid-2\") VARCHAR(\"PREPARE\")]", + "delete:[VARCHAR(\"dtid-2\") VARCHAR(\"PREPARE\")]", + }, + "ks.redo_statement:-80": { + "insert:[VARCHAR(\"dtid-2\") INT64(1) BLOB(\"update twopc_user set `name` = 'newfoo' where id = 8 limit 10001 /* INT64 */\")]", + "delete:[VARCHAR(\"dtid-2\") INT64(1) BLOB(\"update twopc_user set `name` = 'newfoo' where id = 8 limit 10001 /* INT64 */\")]", + }, + "ks.twopc_user:-80": {"update:[INT64(8) VARCHAR(\"newfoo\")]"}, + "ks.twopc_user:80-": {"update:[INT64(7) VARCHAR(\"newfoo\")]"}, + } + assert.Equal(t, expectations, logTable, + "mismatch expected: \n got: %s, want: %s", prettyPrint(logTable), prettyPrint(expectations)) + + // DELETE from multiple shard + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "delete from twopc_user where id = 9") + utils.Exec(t, conn, "delete from twopc_user where id = 10") + utils.Exec(t, conn, "commit") + + logTable = retrieveTransitions(t, ch, tableMap, dtMap) + expectations = map[string][]string{ + "ks.dt_state:80-": { + "insert:[VARCHAR(\"dtid-3\") VARCHAR(\"PREPARE\")]", + "update:[VARCHAR(\"dtid-3\") VARCHAR(\"COMMIT\")]", + "delete:[VARCHAR(\"dtid-3\") VARCHAR(\"COMMIT\")]", + }, + "ks.dt_participant:80-": { + "insert:[VARCHAR(\"dtid-3\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + "delete:[VARCHAR(\"dtid-3\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + }, + "ks.redo_state:-80": { + "insert:[VARCHAR(\"dtid-3\") VARCHAR(\"PREPARE\")]", + "delete:[VARCHAR(\"dtid-3\") VARCHAR(\"PREPARE\")]", + }, + "ks.redo_statement:-80": { + "insert:[VARCHAR(\"dtid-3\") INT64(1) BLOB(\"delete from twopc_user where id = 10 limit 10001 /* INT64 */\")]", + "delete:[VARCHAR(\"dtid-3\") INT64(1) BLOB(\"delete from twopc_user where id = 10 limit 10001 /* INT64 */\")]", + }, + "ks.twopc_user:-80": {"delete:[INT64(10) VARCHAR(\"apa\")]"}, + "ks.twopc_user:80-": {"delete:[INT64(9) VARCHAR(\"baz\")]"}, + } + assert.Equal(t, expectations, logTable, + "mismatch expected: \n got: %s, want: %s", prettyPrint(logTable), prettyPrint(expectations)) +} + +// TestDTRollback tests distributed transaction rollback for insert, update and delete operations +// There would not be any binlog events for rollback +func TestDTRollback(t *testing.T) { + conn, closer := start(t) + defer closer() + + // Insert initial Data + utils.Exec(t, conn, "insert into twopc_user(id, name) values(7,'foo'), (8,'bar')") + + // run vstream to stream binlogs + vtgateConn, err := cluster.DialVTGate(context.Background(), t.Name(), vtgateGrpcAddress, "fk_user", "") + require.NoError(t, err) + defer vtgateConn.Close() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ch := make(chan *binlogdatapb.VEvent) + runVStream(t, ctx, ch, vtgateConn) + + // Insert into multiple shards + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "insert into twopc_user(id, name) values(9,'baz')") + utils.Exec(t, conn, "insert into twopc_user(id, name) values(10,'apa')") + utils.Exec(t, conn, "rollback") + + tableMap := make(map[string][]*querypb.Field) + logTable := retrieveTransitions(t, ch, tableMap, nil) + assert.Zero(t, len(logTable), + "no change in binlog expected: got: %s", prettyPrint(logTable)) + + // Update from multiple shard + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "update twopc_user set name='newfoo' where id = 7") + utils.Exec(t, conn, "update twopc_user set name='newfoo' where id = 8") + utils.Exec(t, conn, "rollback") + + logTable = retrieveTransitions(t, ch, tableMap, nil) + assert.Zero(t, len(logTable), + "no change in binlog expected: got: %s", prettyPrint(logTable)) + + // DELETE from multiple shard + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "delete from twopc_user where id = 7") + utils.Exec(t, conn, "delete from twopc_user where id = 8") + utils.Exec(t, conn, "rollback") + + logTable = retrieveTransitions(t, ch, tableMap, nil) + assert.Zero(t, len(logTable), + "no change in binlog expected: got: %s", prettyPrint(logTable)) +} + +// TestDTCommitMultiShardTxSingleShardDML tests distributed transaction commit for insert, update and delete operations +// There is DML operation only on single shard but transaction open on multiple shards. +// Metdata Manager is the one which executed the DML operation on the shard. +func TestDTCommitDMLOnlyOnMM(t *testing.T) { + conn, closer := start(t) + defer closer() + + vtgateConn, err := cluster.DialVTGate(context.Background(), t.Name(), vtgateGrpcAddress, "fk_user", "") + require.NoError(t, err) + defer vtgateConn.Close() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ch := make(chan *binlogdatapb.VEvent) + runVStream(t, ctx, ch, vtgateConn) + + // Insert into multiple shards + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "insert into twopc_user(id, name) values(7,'foo')") + utils.Exec(t, conn, "select * from twopc_user") + utils.Exec(t, conn, "commit") + + tableMap := make(map[string][]*querypb.Field) + dtMap := make(map[string]string) + logTable := retrieveTransitions(t, ch, tableMap, dtMap) + expectations := map[string][]string{ + "ks.dt_state:80-": { + "insert:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + "update:[VARCHAR(\"dtid-1\") VARCHAR(\"COMMIT\")]", + "delete:[VARCHAR(\"dtid-1\") VARCHAR(\"COMMIT\")]", + }, + "ks.dt_participant:80-": { + "insert:[VARCHAR(\"dtid-1\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + }, + "ks.twopc_user:80-": {"insert:[INT64(7) VARCHAR(\"foo\")]"}, + } + assert.Equal(t, expectations, logTable, + "mismatch expected: \n got: %s, want: %s", prettyPrint(logTable), prettyPrint(expectations)) + + // Update from multiple shard + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "update twopc_user set name='newfoo' where id = 7") + utils.Exec(t, conn, "select * from twopc_user") + utils.Exec(t, conn, "commit") + + logTable = retrieveTransitions(t, ch, tableMap, dtMap) + expectations = map[string][]string{ + "ks.dt_state:80-": { + "insert:[VARCHAR(\"dtid-2\") VARCHAR(\"PREPARE\")]", + "update:[VARCHAR(\"dtid-2\") VARCHAR(\"COMMIT\")]", + "delete:[VARCHAR(\"dtid-2\") VARCHAR(\"COMMIT\")]", + }, + "ks.dt_participant:80-": { + "insert:[VARCHAR(\"dtid-2\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + "delete:[VARCHAR(\"dtid-2\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + }, + "ks.twopc_user:80-": {"update:[INT64(7) VARCHAR(\"newfoo\")]"}, + } + assert.Equal(t, expectations, logTable, + "mismatch expected: \n got: %s, want: %s", prettyPrint(logTable), prettyPrint(expectations)) + + // DELETE from multiple shard + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "delete from twopc_user where id = 7") + utils.Exec(t, conn, "select * from twopc_user") + utils.Exec(t, conn, "commit") + + logTable = retrieveTransitions(t, ch, tableMap, dtMap) + expectations = map[string][]string{ + "ks.dt_state:80-": { + "insert:[VARCHAR(\"dtid-3\") VARCHAR(\"PREPARE\")]", + "update:[VARCHAR(\"dtid-3\") VARCHAR(\"COMMIT\")]", + "delete:[VARCHAR(\"dtid-3\") VARCHAR(\"COMMIT\")]", + }, + "ks.dt_participant:80-": { + "insert:[VARCHAR(\"dtid-3\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + "delete:[VARCHAR(\"dtid-3\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + }, + "ks.twopc_user:80-": {"delete:[INT64(7) VARCHAR(\"newfoo\")]"}, + } + assert.Equal(t, expectations, logTable, + "mismatch expected: \n got: %s, want: %s", prettyPrint(logTable), prettyPrint(expectations)) +} + +// TestDTCommitMultiShardTxSingleShardDML tests distributed transaction commit for insert, update and delete operations +// There is DML operation only on single shard but transaction open on multiple shards. +// Resource Manager is the one which executed the DML operation on the shard. +func TestDTCommitDMLOnlyOnRM(t *testing.T) { + conn, closer := start(t) + defer closer() + + vtgateConn, err := cluster.DialVTGate(context.Background(), t.Name(), vtgateGrpcAddress, "fk_user", "") + require.NoError(t, err) + defer vtgateConn.Close() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ch := make(chan *binlogdatapb.VEvent) + runVStream(t, ctx, ch, vtgateConn) + + // Insert into multiple shards + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "select * from twopc_user where id = 8") + utils.Exec(t, conn, "insert into twopc_user(id, name) values(7,'foo')") + utils.Exec(t, conn, "commit") + + tableMap := make(map[string][]*querypb.Field) + dtMap := make(map[string]string) + logTable := retrieveTransitions(t, ch, tableMap, dtMap) + expectations := map[string][]string{ + "ks.dt_state:-80": { + "insert:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + "update:[VARCHAR(\"dtid-1\") VARCHAR(\"COMMIT\")]", + "delete:[VARCHAR(\"dtid-1\") VARCHAR(\"COMMIT\")]", + }, + "ks.dt_participant:-80": { + "insert:[VARCHAR(\"dtid-1\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"80-\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"80-\")]", + }, + "ks.redo_state:80-": { + "insert:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + "delete:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + }, + "ks.redo_statement:80-": { + "insert:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"insert into twopc_user(id, `name`) values (7, 'foo')\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"insert into twopc_user(id, `name`) values (7, 'foo')\")]", + }, + "ks.twopc_user:80-": {"insert:[INT64(7) VARCHAR(\"foo\")]"}, + } + assert.Equal(t, expectations, logTable, + "mismatch expected: \n got: %s, want: %s", prettyPrint(logTable), prettyPrint(expectations)) + + // Update from multiple shard + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "select * from twopc_user where id = 8") + utils.Exec(t, conn, "update twopc_user set name='newfoo' where id = 7") + utils.Exec(t, conn, "commit") + + logTable = retrieveTransitions(t, ch, tableMap, dtMap) + expectations = map[string][]string{ + "ks.dt_state:-80": { + "insert:[VARCHAR(\"dtid-2\") VARCHAR(\"PREPARE\")]", + "update:[VARCHAR(\"dtid-2\") VARCHAR(\"COMMIT\")]", + "delete:[VARCHAR(\"dtid-2\") VARCHAR(\"COMMIT\")]", + }, + "ks.dt_participant:-80": { + "insert:[VARCHAR(\"dtid-2\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"80-\")]", + "delete:[VARCHAR(\"dtid-2\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"80-\")]", + }, + "ks.redo_state:80-": { + "insert:[VARCHAR(\"dtid-2\") VARCHAR(\"PREPARE\")]", + "delete:[VARCHAR(\"dtid-2\") VARCHAR(\"PREPARE\")]", + }, + "ks.redo_statement:80-": { + "insert:[VARCHAR(\"dtid-2\") INT64(1) BLOB(\"update twopc_user set `name` = 'newfoo' where id = 7 limit 10001 /* INT64 */\")]", + "delete:[VARCHAR(\"dtid-2\") INT64(1) BLOB(\"update twopc_user set `name` = 'newfoo' where id = 7 limit 10001 /* INT64 */\")]", + }, + "ks.twopc_user:80-": {"update:[INT64(7) VARCHAR(\"newfoo\")]"}, + } + assert.Equal(t, expectations, logTable, + "mismatch expected: \n got: %s, want: %s", prettyPrint(logTable), prettyPrint(expectations)) + + // DELETE from multiple shard + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "select * from twopc_user where id = 8") + utils.Exec(t, conn, "delete from twopc_user where id = 7") + utils.Exec(t, conn, "commit") + + logTable = retrieveTransitions(t, ch, tableMap, dtMap) + expectations = map[string][]string{ + "ks.dt_state:-80": { + "insert:[VARCHAR(\"dtid-3\") VARCHAR(\"PREPARE\")]", + "update:[VARCHAR(\"dtid-3\") VARCHAR(\"COMMIT\")]", + "delete:[VARCHAR(\"dtid-3\") VARCHAR(\"COMMIT\")]", + }, + "ks.dt_participant:-80": { + "insert:[VARCHAR(\"dtid-3\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"80-\")]", + "delete:[VARCHAR(\"dtid-3\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"80-\")]", + }, + "ks.redo_state:80-": { + "insert:[VARCHAR(\"dtid-3\") VARCHAR(\"PREPARE\")]", + "delete:[VARCHAR(\"dtid-3\") VARCHAR(\"PREPARE\")]", + }, + "ks.redo_statement:80-": { + "insert:[VARCHAR(\"dtid-3\") INT64(1) BLOB(\"delete from twopc_user where id = 7 limit 10001 /* INT64 */\")]", + "delete:[VARCHAR(\"dtid-3\") INT64(1) BLOB(\"delete from twopc_user where id = 7 limit 10001 /* INT64 */\")]", + }, + "ks.twopc_user:80-": {"delete:[INT64(7) VARCHAR(\"newfoo\")]"}, + } + assert.Equal(t, expectations, logTable, + "mismatch expected: \n got: %s, want: %s", prettyPrint(logTable), prettyPrint(expectations)) +} + +// TestDTPrepareFailOnRM tests distributed transaction prepare failure on resource manager +func TestDTPrepareFailOnRM(t *testing.T) { + conn, closer := start(t) + defer closer() + + vtgateConn, err := cluster.DialVTGate(context.Background(), t.Name(), vtgateGrpcAddress, "fk_user", "") + require.NoError(t, err) + defer vtgateConn.Close() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ch := make(chan *binlogdatapb.VEvent) + runVStream(t, ctx, ch, vtgateConn) + + // Insert into multiple shards + utils.Exec(t, conn, "begin") + utils.Exec(t, conn, "insert into twopc_user(id, name) values(7,'foo')") + utils.Exec(t, conn, "insert into twopc_user(id, name) values(8,'bar')") + + ctx2 := context.Background() + conn2, err := mysql.Connect(ctx2, &vtParams) + require.NoError(t, err) + + utils.Exec(t, conn2, "begin") + utils.Exec(t, conn2, "insert into twopc_user(id, name) values(9,'baz')") + utils.Exec(t, conn2, "insert into twopc_user(id, name) values(10,'apa')") + + var wg sync.WaitGroup + wg.Add(2) + var commitErr error + go func() { + _, err := utils.ExecAllowError(t, conn, "commit") + if err != nil { + commitErr = err + } + wg.Done() + }() + go func() { + _, err := utils.ExecAllowError(t, conn2, "commit") + wg.Done() + if err != nil { + commitErr = err + } + }() + wg.Wait() + require.ErrorContains(t, commitErr, "ResourceExhausted desc = prepare failed") + + tableMap := make(map[string][]*querypb.Field) + dtMap := make(map[string]string) + logTable := retrieveTransitions(t, ch, tableMap, dtMap) + expectations := map[string][]string{ + "ks.dt_state:80-": { + "insert:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + "insert:[VARCHAR(\"dtid-2\") VARCHAR(\"PREPARE\")]", + "update:[VARCHAR(\"dtid-1\") VARCHAR(\"COMMIT\")]", + "update:[VARCHAR(\"dtid-2\") VARCHAR(\"ROLLBACK\")]", + "delete:[VARCHAR(\"dtid-1\") VARCHAR(\"COMMIT\")]", + "delete:[VARCHAR(\"dtid-2\") VARCHAR(\"ROLLBACK\")]", + }, + "ks.dt_participant:80-": { + "insert:[VARCHAR(\"dtid-1\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + "insert:[VARCHAR(\"dtid-2\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + "delete:[VARCHAR(\"dtid-2\") INT64(1) VARCHAR(\"ks\") VARCHAR(\"-80\")]", + }, + "ks.redo_state:-80": { + "insert:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + "delete:[VARCHAR(\"dtid-1\") VARCHAR(\"PREPARE\")]", + }, + "ks.redo_statement:-80": { /* flexi Expectation */ }, + "ks.twopc_user:-80": { /* flexi Expectation */ }, + "ks.twopc_user:80-": { /* flexi Expectation */ }, + } + flexiExpectations := map[string][2][]string{ + "ks.redo_statement:-80": {{ + "insert:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"insert into twopc_user(id, `name`) values (8, 'bar')\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"insert into twopc_user(id, `name`) values (8, 'bar')\")]", + }, { + "insert:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"insert into twopc_user(id, `name`) values (10, 'apa')\")]", + "delete:[VARCHAR(\"dtid-1\") INT64(1) BLOB(\"insert into twopc_user(id, `name`) values (10, 'apa')\")]", + }}, + "ks.twopc_user:-80": {{ + "insert:[INT64(8) VARCHAR(\"bar\")]", + }, { + "insert:[INT64(10) VARCHAR(\"apa\")]", + }}, + "ks.twopc_user:80-": {{ + "insert:[INT64(7) VARCHAR(\"foo\")]", + }, { + "insert:[INT64(9) VARCHAR(\"baz\")]", + }}, + } + + compareMaps(t, expectations, logTable, flexiExpectations) +} + +func compareMaps(t *testing.T, expected, actual map[string][]string, flexibleExp map[string][2][]string) { + assert.Equal(t, len(expected), len(actual), "mismatch in number of keys: expected: %d, got: %d", len(expected), len(actual)) + + for key, expectedValue := range expected { + actualValue, ok := actual[key] + require.Truef(t, ok, "key %s not found in actual map", key) + + if validValues, isFlexi := flexibleExp[key]; isFlexi { + // For the flexible key, check if the actual value matches one of the valid values + if !reflect.DeepEqual(actualValue, validValues[0]) && !reflect.DeepEqual(actualValue, validValues[1]) { + t.Fatalf("mismatch in values for key '%s': expected one of: %v, got: %v", key, validValues, actualValue) + } + } else { + // Sort the slices before comparison + sort.Strings(expectedValue) + sort.Strings(actualValue) + assert.Equal(t, expectedValue, actualValue, "mismatch in values for key %s: expected: %v, got: %v", key, expectedValue, actualValue) + } + } +} diff --git a/go/test/endtoend/vtgate/transaction/twopc/vschema.json b/go/test/endtoend/vtgate/transaction/twopc/vschema.json new file mode 100644 index 00000000000..4ff62df6808 --- /dev/null +++ b/go/test/endtoend/vtgate/transaction/twopc/vschema.json @@ -0,0 +1,26 @@ +{ + "sharded":true, + "vindexes": { + "xxhash": { + "type": "xxhash" + } + }, + "tables": { + "twopc_user":{ + "column_vindexes": [ + { + "column": "id", + "name": "xxhash" + } + ] + }, + "twopc_music": { + "column_vindexes": [ + { + "column": "user_id", + "name": "xxhash" + } + ] + } + } +} \ No newline at end of file diff --git a/go/vt/vttablet/tabletserver/twopc.go b/go/vt/vttablet/tabletserver/twopc.go index bbc54b8ea57..e53dd40ca8a 100644 --- a/go/vt/vttablet/tabletserver/twopc.go +++ b/go/vt/vttablet/tabletserver/twopc.go @@ -86,6 +86,10 @@ type TwoPC struct { // NewTwoPC creates a TwoPC variable. func NewTwoPC(readPool *connpool.Pool) *TwoPC { tpc := &TwoPC{readPool: readPool} + return tpc +} + +func (tpc *TwoPC) initializeQueries() { dbname := sidecar.GetIdentifier() tpc.insertRedoTx = sqlparser.BuildParsedQuery( "insert into %s.redo_state(dtid, state, time_created) values (%a, %a, %a)", @@ -132,7 +136,6 @@ func NewTwoPC(readPool *connpool.Pool) *TwoPC { "select dtid, time_created from %s.dt_state where time_created < %a", dbname, ":time_created") tpc.readAllTransactions = fmt.Sprintf(sqlReadAllTransactions, dbname, dbname) - return tpc } // Open starts the TwoPC service. @@ -143,6 +146,7 @@ func (tpc *TwoPC) Open(dbconfigs *dbconfigs.DBConfigs) error { } defer conn.Close() tpc.readPool.Open(dbconfigs.AppWithDB(), dbconfigs.DbaWithDB(), dbconfigs.DbaWithDB()) + tpc.initializeQueries() log.Infof("TwoPC: Engine open succeeded") return nil } diff --git a/test/config.json b/test/config.json index 9f753f37ba8..713faf97024 100644 --- a/test/config.json +++ b/test/config.json @@ -824,6 +824,15 @@ "RetryMax": 1, "Tags": [] }, + "vtgate_transaction_twopc": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/transaction/twopc"], + "Command": [], + "Manual": false, + "Shard": "vtgate_transaction", + "RetryMax": 1, + "Tags": [] + }, "vtgate_transaction_partial_exec": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/partialfailure"], From 9d63ab40309e414d4a3429bc63bdcbd5ab5136b7 Mon Sep 17 00:00:00 2001 From: Arihant Pal Date: Fri, 14 Jun 2024 16:13:39 +0300 Subject: [PATCH 38/40] test: Replace t.fatalf with testify require (#16038) --- go/tools/asthelpergen/asthelpergen_test.go | 4 +- go/trace/trace_test.go | 9 +- go/vt/binlog/binlog_streamer_rbr_test.go | 33 ++---- go/vt/binlog/tables_filter_test.go | 18 ++-- go/vt/wrangler/tablet_test.go | 115 +++++++++------------ go/vt/wrangler/vexec_test.go | 11 +- go/vt/zkctl/zkctl_test.go | 35 +++---- 7 files changed, 80 insertions(+), 145 deletions(-) diff --git a/go/tools/asthelpergen/asthelpergen_test.go b/go/tools/asthelpergen/asthelpergen_test.go index ce5a59c84e7..19ac865575d 100644 --- a/go/tools/asthelpergen/asthelpergen_test.go +++ b/go/tools/asthelpergen/asthelpergen_test.go @@ -42,8 +42,6 @@ func TestFullGeneration(t *testing.T) { require.Contains(t, contents, "http://www.apache.org/licenses/LICENSE-2.0") applyIdx := strings.Index(contents, "func (a *application) apply(parent, node AST, replacer replacerFunc)") cloneIdx := strings.Index(contents, "CloneAST(in AST) AST") - if applyIdx == 0 && cloneIdx == 0 { - t.Fatalf("file doesn't contain expected contents") - } + require.False(t, applyIdx == 0 && cloneIdx == 0, "file doesn't contain expected contents") } } diff --git a/go/trace/trace_test.go b/go/trace/trace_test.go index 7f1f6d8c528..688d60551e3 100644 --- a/go/trace/trace_test.go +++ b/go/trace/trace_test.go @@ -60,14 +60,9 @@ func TestRegisterService(t *testing.T) { serviceName := "vtservice" closer := StartTracing(serviceName) - tracer, ok := closer.(*fakeTracer) - if !ok { - t.Fatalf("did not get the expected tracer, got %+v (%T)", tracer, tracer) - } + tracer := closer.(*fakeTracer) - if tracer.name != serviceName { - t.Fatalf("expected the name to be `%v` but it was `%v`", serviceName, tracer.name) - } + require.Equal(t, serviceName, tracer.name, fmt.Sprintf("tracer name mismatch: expected %s, got %s", serviceName, tracer.name)) } func TestNewFromString(t *testing.T) { diff --git a/go/vt/binlog/binlog_streamer_rbr_test.go b/go/vt/binlog/binlog_streamer_rbr_test.go index 1678b086719..6ae9bc4afcf 100644 --- a/go/vt/binlog/binlog_streamer_rbr_test.go +++ b/go/vt/binlog/binlog_streamer_rbr_test.go @@ -18,9 +18,10 @@ package binlog import ( "context" - "reflect" "testing" + "github.com/stretchr/testify/assert" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/binlog" "vitess.io/vitess/go/mysql/collations" @@ -270,19 +271,8 @@ func TestStreamerParseRBREvents(t *testing.T) { go sendTestEvents(events, input) _, err := bls.parseEvents(context.Background(), events, errs) - if err != ErrServerEOF { - t.Errorf("unexpected error: %v", err) - } - - if !reflect.DeepEqual(got, want) { - t.Errorf("binlogConnStreamer.parseEvents(): got:\n%+v\nwant:\n%+v", got, want) - for i, fbt := range got { - t.Errorf("Got (%v)=%v", i, fbt.statements) - } - for i, fbt := range want { - t.Errorf("Want(%v)=%v", i, fbt.statements) - } - } + assert.EqualError(t, err, ErrServerEOF.Error(), "unexpected error") + assert.Equal(t, want, got, "binlogConnStreamer.parseEvents()") } func TestStreamerParseRBRNameEscapes(t *testing.T) { @@ -519,17 +509,6 @@ func TestStreamerParseRBRNameEscapes(t *testing.T) { go sendTestEvents(events, input) _, err := bls.parseEvents(context.Background(), events, errs) - if err != ErrServerEOF { - t.Errorf("unexpected error: %v", err) - } - - if !reflect.DeepEqual(got, want) { - t.Errorf("binlogConnStreamer.parseEvents(): got:\n%+v\nwant:\n%+v", got, want) - for i, fbt := range got { - t.Errorf("Got (%v)=%v", i, fbt.statements) - } - for i, fbt := range want { - t.Errorf("Want(%v)=%v", i, fbt.statements) - } - } + assert.EqualError(t, err, ErrServerEOF.Error(), "unexpected error") + assert.Equal(t, want, got, "binlogConnStreamer.parseEvents()") } diff --git a/go/vt/binlog/tables_filter_test.go b/go/vt/binlog/tables_filter_test.go index 0c6aeef3fcc..c65f64b5aef 100644 --- a/go/vt/binlog/tables_filter_test.go +++ b/go/vt/binlog/tables_filter_test.go @@ -20,6 +20,8 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/assert" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" ) @@ -60,9 +62,7 @@ func TestTablesFilterPass(t *testing.T) { }) _ = f(eventToken, statements) want := `statement: <6, "set1"> statement: <7, "dml1 /* _stream included1 (id ) (500 ); */"> statement: <7, "dml2 /* _stream included2 (id ) (500 ); */"> position: "MariaDB/0-41983-1" ` - if want != got { - t.Errorf("want\n%s, got\n%s", want, got) - } + assert.Equal(t, want, got, "binlogConnStreamer.tablesFilterFunc()") } func TestTablesFilterSkip(t *testing.T) { @@ -90,9 +90,7 @@ func TestTablesFilterSkip(t *testing.T) { }) _ = f(eventToken, statements) want := `position: "MariaDB/0-41983-1" ` - if want != got { - t.Errorf("want %s, got %s", want, got) - } + assert.Equal(t, want, got, "binlogConnStreamer.tablesFilterFunc()") } func TestTablesFilterDDL(t *testing.T) { @@ -120,9 +118,7 @@ func TestTablesFilterDDL(t *testing.T) { }) _ = f(eventToken, statements) want := `position: "MariaDB/0-41983-1" ` - if want != got { - t.Errorf("want %s, got %s", want, got) - } + assert.Equal(t, want, got, "binlogConnStreamer.tablesFilterFunc()") } func TestTablesFilterMalformed(t *testing.T) { @@ -156,9 +152,7 @@ func TestTablesFilterMalformed(t *testing.T) { }) _ = f(eventToken, statements) want := `position: "MariaDB/0-41983-1" ` - if want != got { - t.Errorf("want %s, got %s", want, got) - } + assert.Equal(t, want, got, "binlogConnStreamer.tablesFilterFunc()") } func bltToString(tx *binlogdatapb.BinlogTransaction) string { diff --git a/go/vt/wrangler/tablet_test.go b/go/vt/wrangler/tablet_test.go index c5ae032fe07..113743d9c19 100644 --- a/go/vt/wrangler/tablet_test.go +++ b/go/vt/wrangler/tablet_test.go @@ -18,9 +18,10 @@ package wrangler import ( "context" - "strings" "testing" + "github.com/stretchr/testify/require" + "vitess.io/vitess/go/vt/logutil" topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" @@ -48,20 +49,14 @@ func TestInitTabletShardConversion(t *testing.T) { Shard: "80-C0", } - if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { - t.Fatalf("InitTablet failed: %v", err) - } + err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/) + require.NoError(t, err) ti, err := ts.GetTablet(context.Background(), tablet.Alias) - if err != nil { - t.Fatalf("GetTablet failed: %v", err) - } - if ti.Shard != "80-c0" { - t.Errorf("Got wrong tablet.Shard, got %v expected 80-c0", ti.Shard) - } - if string(ti.KeyRange.Start) != "\x80" || string(ti.KeyRange.End) != "\xc0" { - t.Errorf("Got wrong tablet.KeyRange, got %v expected 80-c0", ti.KeyRange) - } + require.NoError(t, err) + require.Equal(t, "80-c0", ti.Shard, "Got wrong tablet.Shard") + require.Equal(t, "\x80", string(ti.KeyRange.Start), "Got wrong tablet.KeyRange start") + require.Equal(t, "\xc0", string(ti.KeyRange.End), "Got wrong tablet.KeyRange end") } // TestDeleteTabletBasic tests delete of non-primary tablet @@ -82,17 +77,14 @@ func TestDeleteTabletBasic(t *testing.T) { Keyspace: "test", } - if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { - t.Fatalf("InitTablet failed: %v", err) - } + err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/) + require.NoError(t, err) - if _, err := ts.GetTablet(context.Background(), tablet.Alias); err != nil { - t.Fatalf("GetTablet failed: %v", err) - } + _, err = ts.GetTablet(context.Background(), tablet.Alias) + require.NoError(t, err) - if err := wr.DeleteTablet(context.Background(), tablet.Alias, false); err != nil { - t.Fatalf("DeleteTablet failed: %v", err) - } + err = wr.DeleteTablet(context.Background(), tablet.Alias, false) + require.NoError(t, err) } // TestDeleteTabletTruePrimary tests that you can delete a true primary tablet @@ -115,31 +107,26 @@ func TestDeleteTabletTruePrimary(t *testing.T) { Type: topodatapb.TabletType_PRIMARY, } - if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { - t.Fatalf("InitTablet failed: %v", err) - } - if _, err := ts.GetTablet(context.Background(), tablet.Alias); err != nil { - t.Fatalf("GetTablet failed: %v", err) - } + err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/) + require.NoError(t, err) + + _, err = ts.GetTablet(context.Background(), tablet.Alias) + require.NoError(t, err) // set PrimaryAlias and PrimaryTermStartTime on shard to match chosen primary tablet - if _, err := ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error { + _, err = ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error { si.PrimaryAlias = tablet.Alias si.PrimaryTermStartTime = tablet.PrimaryTermStartTime return nil - }); err != nil { - t.Fatalf("UpdateShardFields failed: %v", err) - } + }) + require.NoError(t, err) - err := wr.DeleteTablet(context.Background(), tablet.Alias, false) + err = wr.DeleteTablet(context.Background(), tablet.Alias, false) wantError := "as it is a primary, use allow_primary flag" - if err == nil || !strings.Contains(err.Error(), wantError) { - t.Fatalf("DeleteTablet on primary: want error = %v, got error = %v", wantError, err) - } + require.ErrorContains(t, err, wantError, "DeleteTablet on primary: want specific error message") - if err := wr.DeleteTablet(context.Background(), tablet.Alias, true); err != nil { - t.Fatalf("DeleteTablet failed: %v", err) - } + err = wr.DeleteTablet(context.Background(), tablet.Alias, true) + require.NoError(t, err) } // TestDeleteTabletFalsePrimary tests that you can delete a false primary tablet @@ -162,9 +149,8 @@ func TestDeleteTabletFalsePrimary(t *testing.T) { Type: topodatapb.TabletType_PRIMARY, } - if err := wr.TopoServer().InitTablet(context.Background(), tablet1, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { - t.Fatalf("InitTablet failed: %v", err) - } + err := wr.TopoServer().InitTablet(context.Background(), tablet1, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/) + require.NoError(t, err) tablet2 := &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{ @@ -175,23 +161,20 @@ func TestDeleteTabletFalsePrimary(t *testing.T) { Shard: "0", Type: topodatapb.TabletType_PRIMARY, } - if err := wr.TopoServer().InitTablet(context.Background(), tablet2, true /*allowPrimaryOverride*/, false /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { - t.Fatalf("InitTablet failed: %v", err) - } + err = wr.TopoServer().InitTablet(context.Background(), tablet2, true /*allowPrimaryOverride*/, false /*createShardAndKeyspace*/, false /*allowUpdate*/) + require.NoError(t, err) // set PrimaryAlias and PrimaryTermStartTime on shard to match chosen primary tablet - if _, err := ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error { + _, err = ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error { si.PrimaryAlias = tablet2.Alias si.PrimaryTermStartTime = tablet2.PrimaryTermStartTime return nil - }); err != nil { - t.Fatalf("UpdateShardFields failed: %v", err) - } + }) + require.NoError(t, err) // Should be able to delete old (false) primary with allowPrimary = false - if err := wr.DeleteTablet(context.Background(), tablet1.Alias, false); err != nil { - t.Fatalf("DeleteTablet failed: %v", err) - } + err = wr.DeleteTablet(context.Background(), tablet1.Alias, false) + require.NoError(t, err) } // TestDeleteTabletShardNonExisting tests that you can delete a true primary @@ -214,29 +197,25 @@ func TestDeleteTabletShardNonExisting(t *testing.T) { Type: topodatapb.TabletType_PRIMARY, } - if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil { - t.Fatalf("InitTablet failed: %v", err) - } - if _, err := ts.GetTablet(context.Background(), tablet.Alias); err != nil { - t.Fatalf("GetTablet failed: %v", err) - } + err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/) + require.NoError(t, err) + + _, err = ts.GetTablet(context.Background(), tablet.Alias) + require.NoError(t, err) // set PrimaryAlias and PrimaryTermStartTime on shard to match chosen primary tablet - if _, err := ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error { + _, err = ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error { si.PrimaryAlias = tablet.Alias si.PrimaryTermStartTime = tablet.PrimaryTermStartTime return nil - }); err != nil { - t.Fatalf("UpdateShardFields failed: %v", err) - } + }) + require.NoError(t, err) // trigger a shard deletion - if err := ts.DeleteShard(context.Background(), "test", "0"); err != nil { - t.Fatalf("DeleteShard failed: %v", err) - } + err = ts.DeleteShard(context.Background(), "test", "0") + require.NoError(t, err) // DeleteTablet should not fail if a shard no longer exist - if err := wr.DeleteTablet(context.Background(), tablet.Alias, true); err != nil { - t.Fatalf("DeleteTablet failed: %v", err) - } + err = wr.DeleteTablet(context.Background(), tablet.Alias, true) + require.NoError(t, err) } diff --git a/go/vt/wrangler/vexec_test.go b/go/vt/wrangler/vexec_test.go index 27efbe61a9f..80cd2aef565 100644 --- a/go/vt/wrangler/vexec_test.go +++ b/go/vt/wrangler/vexec_test.go @@ -26,6 +26,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqltypes" @@ -151,15 +152,11 @@ func TestVExec(t *testing.T) { if testCase.errorString == "" { require.NoError(t, err) for _, result := range results { - if !testCase.result.Equal(result) { - t.Errorf("mismatched result:\nwant: %v\ngot: %v", testCase.result, result) - } + assert.True(t, testCase.result.Equal(result), "mismatched result") } } else { - require.Error(t, err) - if !strings.Contains(err.Error(), testCase.errorString) { - t.Fatalf("Wrong error, want %s, got %s", testCase.errorString, err.Error()) - } + require.ErrorContains(t, err, testCase.errorString, "Wrong error, want %s, got %s", testCase.errorString, err.Error()) + } }) } diff --git a/go/vt/zkctl/zkctl_test.go b/go/vt/zkctl/zkctl_test.go index 5e4c856b5a7..a0c03a58df2 100644 --- a/go/vt/zkctl/zkctl_test.go +++ b/go/vt/zkctl/zkctl_test.go @@ -18,8 +18,9 @@ package zkctl import ( "fmt" - "strings" "testing" + + "github.com/stretchr/testify/require" ) // This test depend on starting and stopping a ZK instance, @@ -39,29 +40,21 @@ func TestLifeCycle(t *testing.T) { adminServerCfg := "admin.serverPort=8081" zkConf.Extra = []string{tpcKeepAliveCfg, adminServerCfg} - if zkObservedConf, err := MakeZooCfg([]string{zkConf.ConfigFile()}, zkConf, "header"); err != nil { - t.Fatalf("MakeZooCfg err: %v", err) - } else if !strings.Contains(zkObservedConf, fmt.Sprintf("\n%s\n", tpcKeepAliveCfg)) { - t.Fatalf("Expected tpcKeepAliveCfg in zkObservedConf") - } else if !strings.Contains(zkObservedConf, fmt.Sprintf("\n%s\n", adminServerCfg)) { - t.Fatalf("Expected adminServerCfg in zkObservedConf") - } + zkObservedConf, err := MakeZooCfg([]string{zkConf.ConfigFile()}, zkConf, "header") + require.NoError(t, err) + require.Contains(t, zkObservedConf, fmt.Sprintf("\n%s\n", tpcKeepAliveCfg), "Expected tpcKeepAliveCfg in zkObservedConf") + require.Contains(t, zkObservedConf, fmt.Sprintf("\n%s\n", adminServerCfg), "Expected adminServerCfg in zkObservedConf") zkd := NewZkd(zkConf) - if err := zkd.Init(); err != nil { - t.Fatalf("Init() err: %v", err) - } + err = zkd.Init() + require.NoError(t, err) - if err := zkd.Shutdown(); err != nil { - t.Fatalf("Shutdown() err: %v", err) - } + err = zkd.Shutdown() + require.NoError(t, err) - if err := zkd.Start(); err != nil { - t.Fatalf("Start() err: %v", err) - } - - if err := zkd.Teardown(); err != nil { - t.Fatalf("Teardown() err: %v", err) - } + err = zkd.Start() + require.NoError(t, err) + err = zkd.Teardown() + require.NoError(t, err) } From 5a6f3868c56fb6e5290b153a615882c31aedfa6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Fri, 14 Jun 2024 16:08:03 +0200 Subject: [PATCH 39/40] Handle Nullability for Columns from Outer Tables (#16174) Signed-off-by: Andres Taylor --- .../endtoend/vtgate/queries/misc/misc_test.go | 14 +++ .../endtoend/vtgate/queries/misc/schema.sql | 2 +- go/vt/vtgate/evalengine/compiler.go | 4 + .../planbuilder/operator_transformers.go | 14 +-- .../vtgate/planbuilder/operators/distinct.go | 2 +- go/vt/vtgate/planbuilder/operators/filter.go | 2 +- .../vtgate/planbuilder/operators/hash_join.go | 4 +- go/vt/vtgate/planbuilder/operators/insert.go | 4 +- go/vt/vtgate/planbuilder/operators/join.go | 3 + .../planbuilder/operators/projection.go | 2 +- .../planbuilder/operators/queryprojection.go | 2 +- .../planbuilder/operators/sharded_routing.go | 4 +- .../planbuilder/operators/union_merging.go | 4 +- go/vt/vtgate/planbuilder/operators/update.go | 2 +- .../plancontext/planning_context.go | 21 ++++ .../plancontext/planning_context_test.go | 108 ++++++++++++++++++ go/vt/vtgate/semantics/semantic_state.go | 1 + 17 files changed, 172 insertions(+), 21 deletions(-) create mode 100644 go/vt/vtgate/planbuilder/plancontext/planning_context_test.go diff --git a/go/test/endtoend/vtgate/queries/misc/misc_test.go b/go/test/endtoend/vtgate/queries/misc/misc_test.go index 857339605f8..e43171b6701 100644 --- a/go/test/endtoend/vtgate/queries/misc/misc_test.go +++ b/go/test/endtoend/vtgate/queries/misc/misc_test.go @@ -462,6 +462,20 @@ func TestColumnAliases(t *testing.T) { mcmp.ExecWithColumnCompare(`select a as k from (select count(*) as a from t1) t`) } +func TestHandleNullableColumn(t *testing.T) { + utils.SkipIfBinaryIsBelowVersion(t, 21, "vtgate") + require.NoError(t, + utils.WaitForAuthoritative(t, keyspaceName, "tbl", clusterInstance.VtgateProcess.ReadVSchema)) + mcmp, closer := start(t) + defer closer() + + mcmp.Exec("insert into t1(id1, id2) values (0,0), (1,1), (2,2)") + mcmp.Exec("insert into tbl(id, unq_col, nonunq_col) values (0,0,0), (1,1,6)") + // This query tests that we handle nullable columns correctly + // tbl.nonunq_col is not nullable according to the schema, but because of the left join, it can be NULL + mcmp.ExecWithColumnCompare(`select * from t1 left join tbl on t1.id2 = tbl.id where t1.id1 = 6 or tbl.nonunq_col = 6`) +} + func TestEnumSetVals(t *testing.T) { utils.SkipIfBinaryIsBelowVersion(t, 20, "vtgate") diff --git a/go/test/endtoend/vtgate/queries/misc/schema.sql b/go/test/endtoend/vtgate/queries/misc/schema.sql index e0c0d1a36a7..6b860ae77ae 100644 --- a/go/test/endtoend/vtgate/queries/misc/schema.sql +++ b/go/test/endtoend/vtgate/queries/misc/schema.sql @@ -24,7 +24,7 @@ create table tbl ( id bigint, unq_col bigint, - nonunq_col bigint, + nonunq_col bigint not null, primary key (id), unique (unq_col) ) Engine = InnoDB; diff --git a/go/vt/vtgate/evalengine/compiler.go b/go/vt/vtgate/evalengine/compiler.go index d9de15aa571..bcb2281f1a6 100644 --- a/go/vt/vtgate/evalengine/compiler.go +++ b/go/vt/vtgate/evalengine/compiler.go @@ -156,6 +156,10 @@ func (t *Type) Nullable() bool { return true // nullable by default for unknown types } +func (t *Type) SetNullability(n bool) { + t.nullable = n +} + func (t *Type) Values() *EnumSetValues { return t.values } diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 76c4ddd476c..bec5cd28bb5 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -317,7 +317,7 @@ func transformAggregator(ctx *plancontext.PlanningContext, op *operators.Aggrega } for _, groupBy := range op.Grouping { - typ, _ := ctx.SemTable.TypeForExpr(groupBy.Inner) + typ, _ := ctx.TypeForExpr(groupBy.Inner) groupByKeys = append(groupByKeys, &engine.GroupByParams{ KeyCol: groupBy.ColOffset, WeightStringCol: groupBy.WSOffset, @@ -372,7 +372,7 @@ func createMemorySort(ctx *plancontext.PlanningContext, src engine.Primitive, or } for idx, order := range ordering.Order { - typ, _ := ctx.SemTable.TypeForExpr(order.SimplifiedExpr) + typ, _ := ctx.TypeForExpr(order.SimplifiedExpr) prim.OrderBy = append(prim.OrderBy, evalengine.OrderByParams{ Col: ordering.Offset[idx], WeightStringCol: ordering.WOffset[idx], @@ -438,7 +438,7 @@ func getEvalEngineExpr(ctx *plancontext.PlanningContext, pe *operators.ProjExpr) case *operators.EvalEngine: return e.EExpr, nil case operators.Offset: - typ, _ := ctx.SemTable.TypeForExpr(pe.EvalExpr) + typ, _ := ctx.TypeForExpr(pe.EvalExpr) return evalengine.NewColumn(int(e), typ, pe.EvalExpr), nil default: return nil, vterrors.VT13001("project not planned for: %s", pe.String()) @@ -590,7 +590,7 @@ func buildRoutePrimitive(ctx *plancontext.PlanningContext, op *operators.Route, } for _, order := range op.Ordering { - typ, _ := ctx.SemTable.TypeForExpr(order.AST) + typ, _ := ctx.TypeForExpr(order.AST) eroute.OrderBy = append(eroute.OrderBy, evalengine.OrderByParams{ Col: order.Offset, WeightStringCol: order.WOffset, @@ -907,11 +907,11 @@ func transformHashJoin(ctx *plancontext.PlanningContext, op *operators.HashJoin) var missingTypes []string - ltyp, found := ctx.SemTable.TypeForExpr(op.JoinComparisons[0].LHS) + ltyp, found := ctx.TypeForExpr(op.JoinComparisons[0].LHS) if !found { missingTypes = append(missingTypes, sqlparser.String(op.JoinComparisons[0].LHS)) } - rtyp, found := ctx.SemTable.TypeForExpr(op.JoinComparisons[0].RHS) + rtyp, found := ctx.TypeForExpr(op.JoinComparisons[0].RHS) if !found { missingTypes = append(missingTypes, sqlparser.String(op.JoinComparisons[0].RHS)) } @@ -949,7 +949,7 @@ func transformVindexPlan(ctx *plancontext.PlanningContext, op *operators.Vindex) expr, err := evalengine.Translate(op.Value, &evalengine.Config{ Collation: ctx.SemTable.Collation, - ResolveType: ctx.SemTable.TypeForExpr, + ResolveType: ctx.TypeForExpr, Environment: ctx.VSchema.Environment(), }) if err != nil { diff --git a/go/vt/vtgate/planbuilder/operators/distinct.go b/go/vt/vtgate/planbuilder/operators/distinct.go index 9c893a878cd..f24d5b4978b 100644 --- a/go/vt/vtgate/planbuilder/operators/distinct.go +++ b/go/vt/vtgate/planbuilder/operators/distinct.go @@ -54,7 +54,7 @@ func (d *Distinct) planOffsets(ctx *plancontext.PlanningContext) Operator { offset := d.Source.AddWSColumn(ctx, idx, false) wsCol = &offset } - typ, _ := ctx.SemTable.TypeForExpr(e) + typ, _ := ctx.TypeForExpr(e) d.Columns = append(d.Columns, engine.CheckCol{ Col: idx, WsCol: wsCol, diff --git a/go/vt/vtgate/planbuilder/operators/filter.go b/go/vt/vtgate/planbuilder/operators/filter.go index babc309db72..19d864c0ada 100644 --- a/go/vt/vtgate/planbuilder/operators/filter.go +++ b/go/vt/vtgate/planbuilder/operators/filter.go @@ -127,7 +127,7 @@ func (f *Filter) Compact(*plancontext.PlanningContext) (Operator, *ApplyResult) func (f *Filter) planOffsets(ctx *plancontext.PlanningContext) Operator { cfg := &evalengine.Config{ - ResolveType: ctx.SemTable.TypeForExpr, + ResolveType: ctx.TypeForExpr, Collation: ctx.SemTable.Collation, Environment: ctx.VSchema.Environment(), } diff --git a/go/vt/vtgate/planbuilder/operators/hash_join.go b/go/vt/vtgate/planbuilder/operators/hash_join.go index d2ba6522691..1928f4dda9e 100644 --- a/go/vt/vtgate/planbuilder/operators/hash_join.go +++ b/go/vt/vtgate/planbuilder/operators/hash_join.go @@ -358,7 +358,7 @@ func (hj *HashJoin) addColumn(ctx *plancontext.PlanningContext, in sqlparser.Exp rewrittenExpr := sqlparser.CopyOnRewrite(in, pre, r.post, ctx.SemTable.CopySemanticInfo).(sqlparser.Expr) cfg := &evalengine.Config{ - ResolveType: ctx.SemTable.TypeForExpr, + ResolveType: ctx.TypeForExpr, Collation: ctx.SemTable.Collation, Environment: ctx.VSchema.Environment(), } @@ -458,7 +458,7 @@ func (hj *HashJoin) addSingleSidedColumn( rewrittenExpr := sqlparser.CopyOnRewrite(in, pre, r.post, ctx.SemTable.CopySemanticInfo).(sqlparser.Expr) cfg := &evalengine.Config{ - ResolveType: ctx.SemTable.TypeForExpr, + ResolveType: ctx.TypeForExpr, Collation: ctx.SemTable.Collation, Environment: ctx.VSchema.Environment(), } diff --git a/go/vt/vtgate/planbuilder/operators/insert.go b/go/vt/vtgate/planbuilder/operators/insert.go index a009e14f99c..6832dc363d5 100644 --- a/go/vt/vtgate/planbuilder/operators/insert.go +++ b/go/vt/vtgate/planbuilder/operators/insert.go @@ -506,7 +506,7 @@ func insertRowsPlan(ctx *plancontext.PlanningContext, insOp *Insert, ins *sqlpar colNum, _ := findOrAddColumn(ins, col) for rowNum, row := range rows { innerpv, err := evalengine.Translate(row[colNum], &evalengine.Config{ - ResolveType: ctx.SemTable.TypeForExpr, + ResolveType: ctx.TypeForExpr, Collation: ctx.SemTable.Collation, Environment: ctx.VSchema.Environment(), }) @@ -637,7 +637,7 @@ func modifyForAutoinc(ctx *plancontext.PlanningContext, ins *sqlparser.Insert, v } var err error gen.Values, err = evalengine.Translate(autoIncValues, &evalengine.Config{ - ResolveType: ctx.SemTable.TypeForExpr, + ResolveType: ctx.TypeForExpr, Collation: ctx.SemTable.Collation, Environment: ctx.VSchema.Environment(), }) diff --git a/go/vt/vtgate/planbuilder/operators/join.go b/go/vt/vtgate/planbuilder/operators/join.go index d13f79e010f..71d2e5a8048 100644 --- a/go/vt/vtgate/planbuilder/operators/join.go +++ b/go/vt/vtgate/planbuilder/operators/join.go @@ -105,6 +105,9 @@ func createLeftOuterJoin(ctx *plancontext.PlanningContext, join *sqlparser.JoinT joinOp := &Join{LHS: lhs, RHS: rhs, JoinType: join.Join} + // mark the RHS as outer tables so we know which columns are nullable + ctx.OuterTables = ctx.OuterTables.Merge(TableID(rhs)) + // for outer joins we have to be careful with the predicates we use var op Operator subq, _ := getSubQuery(join.Condition.On) diff --git a/go/vt/vtgate/planbuilder/operators/projection.go b/go/vt/vtgate/planbuilder/operators/projection.go index 6326fcd2ac7..527991cba26 100644 --- a/go/vt/vtgate/planbuilder/operators/projection.go +++ b/go/vt/vtgate/planbuilder/operators/projection.go @@ -631,7 +631,7 @@ func (p *Projection) planOffsets(ctx *plancontext.PlanningContext) Operator { // for everything else, we'll turn to the evalengine eexpr, err := evalengine.Translate(rewritten, &evalengine.Config{ - ResolveType: ctx.SemTable.TypeForExpr, + ResolveType: ctx.TypeForExpr, Collation: ctx.SemTable.Collation, Environment: ctx.VSchema.Environment(), }) diff --git a/go/vt/vtgate/planbuilder/operators/queryprojection.go b/go/vt/vtgate/planbuilder/operators/queryprojection.go index 56e0fe8d623..5729dbd0c2e 100644 --- a/go/vt/vtgate/planbuilder/operators/queryprojection.go +++ b/go/vt/vtgate/planbuilder/operators/queryprojection.go @@ -101,7 +101,7 @@ func (aggr Aggr) GetTypeCollation(ctx *plancontext.PlanningContext) evalengine.T } switch aggr.OpCode { case opcode.AggregateMin, opcode.AggregateMax, opcode.AggregateSumDistinct, opcode.AggregateCountDistinct: - typ, _ := ctx.SemTable.TypeForExpr(aggr.Func.GetArg()) + typ, _ := ctx.TypeForExpr(aggr.Func.GetArg()) return typ } diff --git a/go/vt/vtgate/planbuilder/operators/sharded_routing.go b/go/vt/vtgate/planbuilder/operators/sharded_routing.go index 29ee88787b5..1319b76f040 100644 --- a/go/vt/vtgate/planbuilder/operators/sharded_routing.go +++ b/go/vt/vtgate/planbuilder/operators/sharded_routing.go @@ -573,7 +573,7 @@ func (tr *ShardedRouting) planCompositeInOpArg( Key: right.String(), Index: idx, } - if typ, found := ctx.SemTable.TypeForExpr(col); found { + if typ, found := ctx.TypeForExpr(col); found { value.Type = typ.Type() value.Collation = typ.Collation() } @@ -687,7 +687,7 @@ func makeEvalEngineExpr(ctx *plancontext.PlanningContext, n sqlparser.Expr) eval for _, expr := range ctx.SemTable.GetExprAndEqualities(n) { ee, _ := evalengine.Translate(expr, &evalengine.Config{ Collation: ctx.SemTable.Collation, - ResolveType: ctx.SemTable.TypeForExpr, + ResolveType: ctx.TypeForExpr, Environment: ctx.VSchema.Environment(), }) if ee != nil { diff --git a/go/vt/vtgate/planbuilder/operators/union_merging.go b/go/vt/vtgate/planbuilder/operators/union_merging.go index 81ca2f5623e..20c20673665 100644 --- a/go/vt/vtgate/planbuilder/operators/union_merging.go +++ b/go/vt/vtgate/planbuilder/operators/union_merging.go @@ -200,8 +200,8 @@ func createMergedUnion( continue } deps = deps.Merge(ctx.SemTable.RecursiveDeps(rae.Expr)) - rt, foundR := ctx.SemTable.TypeForExpr(rae.Expr) - lt, foundL := ctx.SemTable.TypeForExpr(lae.Expr) + rt, foundR := ctx.TypeForExpr(rae.Expr) + lt, foundL := ctx.TypeForExpr(lae.Expr) if foundR && foundL { collations := ctx.VSchema.Environment().CollationEnv() var typer evalengine.TypeAggregator diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index ba83ad7efaf..e843155246c 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -1123,7 +1123,7 @@ func createAssignmentExpressions( } found = true pv, err := evalengine.Translate(assignment.Expr.EvalExpr, &evalengine.Config{ - ResolveType: ctx.SemTable.TypeForExpr, + ResolveType: ctx.TypeForExpr, Collation: ctx.SemTable.Collation, Environment: ctx.VSchema.Environment(), }) diff --git a/go/vt/vtgate/planbuilder/plancontext/planning_context.go b/go/vt/vtgate/planbuilder/plancontext/planning_context.go index 3c2a1c97434..90a6bdac6f8 100644 --- a/go/vt/vtgate/planbuilder/plancontext/planning_context.go +++ b/go/vt/vtgate/planbuilder/plancontext/planning_context.go @@ -20,6 +20,7 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/evalengine" "vitess.io/vitess/go/vt/vtgate/semantics" ) @@ -57,6 +58,10 @@ type PlanningContext struct { // Statement contains the originally parsed statement Statement sqlparser.Statement + + // OuterTables contains the tables that are outer to the current query + // Used to set the nullable flag on the columns + OuterTables semantics.TableSet } // CreatePlanningContext initializes a new PlanningContext with the given parameters. @@ -201,3 +206,19 @@ func (ctx *PlanningContext) RewriteDerivedTableExpression(expr sqlparser.Expr, t } return modifiedExpr } + +// TypeForExpr returns the type of the given expression, with nullable set if the expression is from an outer table. +func (ctx *PlanningContext) TypeForExpr(e sqlparser.Expr) (evalengine.Type, bool) { + t, found := ctx.SemTable.TypeForExpr(e) + if !found { + return t, found + } + deps := ctx.SemTable.RecursiveDeps(e) + // If the expression is from an outer table, it should be nullable + // There are some exceptions to this, where an expression depending on the outer side + // will never return NULL, but it's better to be conservative here. + if deps.IsOverlapping(ctx.OuterTables) { + t.SetNullability(true) + } + return t, true +} diff --git a/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go b/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go new file mode 100644 index 00000000000..b47286abdb2 --- /dev/null +++ b/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go @@ -0,0 +1,108 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package plancontext + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/vtgate/evalengine" + + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/semantics" +) + +func TestOuterTableNullability(t *testing.T) { + // Tests that columns from outer tables are nullable, + // even though the semantic state says that they are not nullable. + // This is because the outer table may not have a matching row. + // All columns are marked as NOT NULL in the schema. + query := "select * from t1 left join t2 on t1.a = t2.a where t1.a+t2.a/abs(t2.boing)" + ctx, columns := prepareContextAndFindColumns(t, query) + + // Check if the columns are correctly marked as nullable. + for _, col := range columns { + colName := "column: " + sqlparser.String(col) + t.Run(colName, func(t *testing.T) { + // Extract the column type from the context and the semantic state. + // The context should mark the column as nullable. + ctxType, found := ctx.TypeForExpr(col) + require.True(t, found, colName) + stType, found := ctx.SemTable.TypeForExpr(col) + require.True(t, found, colName) + ctxNullable := ctxType.Nullable() + stNullable := stType.Nullable() + + switch col.Qualifier.Name.String() { + case "t1": + assert.False(t, ctxNullable, colName) + assert.False(t, stNullable, colName) + case "t2": + assert.True(t, ctxNullable, colName) + + // The semantic state says that the column is not nullable. Don't trust it. + assert.False(t, stNullable, colName) + } + }) + } +} + +func prepareContextAndFindColumns(t *testing.T, query string) (ctx *PlanningContext, columns []*sqlparser.ColName) { + parser := sqlparser.NewTestParser() + ast, err := parser.Parse(query) + require.NoError(t, err) + semTable := semantics.EmptySemTable() + t1 := semTable.NewTableId() + t2 := semTable.NewTableId() + stmt := ast.(*sqlparser.Select) + expr := stmt.Where.Expr + + // Instead of using the semantic analysis, we manually set the types for the columns. + _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { + col, ok := node.(*sqlparser.ColName) + if !ok { + return true, nil + } + + switch col.Qualifier.Name.String() { + case "t1": + semTable.Recursive[col] = t1 + case "t2": + semTable.Recursive[col] = t2 + } + + intNotNull := evalengine.NewType(sqltypes.Int64, collations.Unknown) + intNotNull.SetNullability(false) + semTable.ExprTypes[col] = intNotNull + columns = append(columns, col) + return false, nil + }, nil, expr) + + ctx = &PlanningContext{ + SemTable: semTable, + joinPredicates: map[sqlparser.Expr][]sqlparser.Expr{}, + skipPredicates: map[sqlparser.Expr]any{}, + ReservedArguments: map[sqlparser.Expr]string{}, + Statement: stmt, + OuterTables: t2, // t2 is the outer table. + } + return +} diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index bedb9105116..1dcaaf87061 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -656,6 +656,7 @@ func (st *SemTable) AddExprs(tbl *sqlparser.AliasedTableExpr, cols sqlparser.Sel } // TypeForExpr returns the type of expressions in the query +// Note that PlanningContext has the same method, and you should use that if you have a PlanningContext func (st *SemTable) TypeForExpr(e sqlparser.Expr) (evalengine.Type, bool) { if typ, found := st.ExprTypes[e]; found { return typ, true From a16a0303e3854da52085a380b37d9002ed1f401a Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:42:58 +0200 Subject: [PATCH 40/40] CI flaky test: Fix flakiness in vreplication_migrate_vdiff2_convert_tz (#16180) Signed-off-by: Rohit Nayak Signed-off-by: Matt Lord Co-authored-by: Matt Lord --- go/test/endtoend/vreplication/migrate_test.go | 14 ++++++++------ go/test/endtoend/vreplication/vdiff2_test.go | 12 ++++++++---- .../endtoend/vreplication/vdiff_helper_test.go | 15 ++++----------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/go/test/endtoend/vreplication/migrate_test.go b/go/test/endtoend/vreplication/migrate_test.go index 1f365c47600..57ec8238d2b 100644 --- a/go/test/endtoend/vreplication/migrate_test.go +++ b/go/test/endtoend/vreplication/migrate_test.go @@ -201,6 +201,8 @@ func TestVtctldMigrate(t *testing.T) { extVtgateConn := getConnection(t, extVc.ClusterConfig.hostname, extVc.ClusterConfig.vtgateMySQLPort) insertInitialDataIntoExternalCluster(t, extVtgateConn) + targetPrimary := vc.getPrimaryTablet(t, "product", "0") + var output, expected string t.Run("mount external cluster", func(t *testing.T) { @@ -232,12 +234,12 @@ func TestVtctldMigrate(t *testing.T) { } waitForWorkflowState(t, vc, ksWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String()) expectNumberOfStreams(t, vtgateConn, "migrate", "e1", "product:0", 1) - waitForRowCount(t, vtgateConn, "product:0", "rating", 2) - waitForRowCount(t, vtgateConn, "product:0", "review", 3) + waitForRowCountInTablet(t, targetPrimary, "product", "rating", 2) + waitForRowCountInTablet(t, targetPrimary, "product", "review", 3) execVtgateQuery(t, extVtgateConn, "rating", "insert into review(rid, pid, review) values(4, 1, 'review4');") execVtgateQuery(t, extVtgateConn, "rating", "insert into rating(gid, pid, rating) values(3, 1, 3);") - waitForRowCount(t, vtgateConn, "product:0", "rating", 3) - waitForRowCount(t, vtgateConn, "product:0", "review", 4) + waitForRowCountInTablet(t, targetPrimary, "product", "rating", 3) + waitForRowCountInTablet(t, targetPrimary, "product", "review", 4) vdiffSideBySide(t, ksWorkflow, "extcell1") output, err = vc.VtctldClient.ExecuteCommandWithOutput("Migrate", @@ -268,8 +270,8 @@ func TestVtctldMigrate(t *testing.T) { require.NoError(t, err, "Migrate command failed with %s", output) expectNumberOfStreams(t, vtgateConn, "migrate", "e1", "product:0", 1, binlogdatapb.VReplicationWorkflowState_Stopped.String()) - waitForRowCount(t, vtgateConn, "product:0", "rating", 0) - waitForRowCount(t, vtgateConn, "product:0", "review", 0) + waitForRowCountInTablet(t, targetPrimary, "product", "rating", 0) + waitForRowCountInTablet(t, targetPrimary, "product", "review", 0) output, err = vc.VtctldClient.ExecuteCommandWithOutput("Migrate", "--target-keyspace", "product", "--workflow", "e1", "cancel") require.NoError(t, err, "Migrate command failed with %s", output) diff --git a/go/test/endtoend/vreplication/vdiff2_test.go b/go/test/endtoend/vreplication/vdiff2_test.go index 08f5bb8926d..fb8ed7c8787 100644 --- a/go/test/endtoend/vreplication/vdiff2_test.go +++ b/go/test/endtoend/vreplication/vdiff2_test.go @@ -306,10 +306,12 @@ func testWorkflow(t *testing.T, vc *VitessCluster, tc *testCase, tks *Keyspace, checkVDiffCountStat(t, statsTablet, tc.vdiffCount) // These are done here so that we have a valid workflow to test the commands against. + if tc.stop { testStop(t, ksWorkflow, allCellNames) tc.vdiffCount++ // We did either vtctlclient OR vtctldclient vdiff create } + if tc.testCLICreateWait { testCLICreateWait(t, ksWorkflow, allCellNames) tc.vdiffCount++ // We did either vtctlclient OR vtctldclient vdiff create @@ -519,14 +521,16 @@ func testResume(t *testing.T, tc *testCase, cells string) { func testStop(t *testing.T, ksWorkflow, cells string) { t.Run("Stop", func(t *testing.T) { - // create a new VDiff and immediately stop it + // Create a new VDiff and immediately stop it. uuid, _ := performVDiff2Action(t, false, ksWorkflow, cells, "create", "", false) _, _ = performVDiff2Action(t, false, ksWorkflow, cells, "stop", uuid, false) - // confirm the VDiff is in the expected stopped state + // Confirm the VDiff is in the expected state. _, output := performVDiff2Action(t, false, ksWorkflow, cells, "show", uuid, false) jsonOutput := getVDiffInfo(output) - require.Equal(t, "stopped", jsonOutput.State) - // confirm that the context cancelled error was also cleared + // It may have been able to complete before we could stop it (there's virtually no data + // to diff). There's no way to avoid this potential race so don't consider that a failure. + require.True(t, (jsonOutput.State == "stopped" || jsonOutput.State == "completed"), "expected vdiff state to be stopped or completed but it was %s", jsonOutput.State) + // Confirm that the context cancelled error was also cleared. require.False(t, strings.Contains(output, `"Errors":`)) }) } diff --git a/go/test/endtoend/vreplication/vdiff_helper_test.go b/go/test/endtoend/vreplication/vdiff_helper_test.go index 53e19e56731..561edfe8b7e 100644 --- a/go/test/endtoend/vreplication/vdiff_helper_test.go +++ b/go/test/endtoend/vreplication/vdiff_helper_test.go @@ -26,10 +26,12 @@ import ( "github.com/stretchr/testify/require" "github.com/tidwall/gjson" + "vitess.io/vitess/go/json2" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/log" - binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" vdiff2 "vitess.io/vitess/go/vt/vttablet/tabletmanager/vdiff" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) const ( @@ -329,16 +331,7 @@ type vdiffInfo struct { func getVDiffInfo(json string) *vdiffInfo { var info vdiffInfo - info.Workflow = gjson.Get(json, "Workflow").String() - info.Keyspace = gjson.Get(json, "Keyspace").String() - info.State = gjson.Get(json, "State").String() - info.Shards = gjson.Get(json, "Shards").String() - info.RowsCompared = gjson.Get(json, "RowsCompared").Int() - info.StartedAt = gjson.Get(json, "StartedAt").String() - info.CompletedAt = gjson.Get(json, "CompletedAt").String() - info.HasMismatch = gjson.Get(json, "HasMismatch").Bool() - info.Progress.Percentage = gjson.Get(json, "Progress.Percentage").Float() - info.Progress.ETA = gjson.Get(json, "Progress.ETA").String() + _ = json2.Unmarshal([]byte(json), &info) return &info }